Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/lib/shared.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export const appName = 'Talo'
export const docsRoute = '/'

export const siteOrigin = 'https://docs.trytalo.com'

export const baseApiUrl = import.meta.env.DEV ? 'http://localhost:3000' : 'https://api.trytalo.com'
2 changes: 1 addition & 1 deletion app/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { index, route, type RouteConfig } from '@react-router/dev/routes'

export default [
index('routes/home.tsx'),
route('intro', 'routes/intro-redirect.tsx'),
route('api/search', 'routes/search.ts'),
route('sitemap.xml', 'routes/sitemap.ts'),
route(':version/*', 'routes/docs.tsx'),
] satisfies RouteConfig
9 changes: 6 additions & 3 deletions app/routes/docs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Feedback } from '@/components/feedback/client'
import { useMDXComponents } from '@/components/mdx'
import { onPageFeedback } from '@/lib/feedback'
import { baseOptions } from '@/lib/layout.shared'
import { siteOrigin } from '@/lib/shared'
import { docs, source } from '@/lib/source'
import type { Route } from './+types/docs'

Expand All @@ -23,11 +24,12 @@ export async function loader({ params }: Route.LoaderArgs) {

return {
path: page.path,
url: page.url,
pageTree: await source.serializePageTree(source.getPageTree()),
}
}

function Content({ path }: { path: string }) {
function Content({ path, url }: { path: string; url: string }) {
const page = docs.getPage(path)
if (!page) {
throw new Error(`unknown page: ${path}`)
Expand All @@ -48,6 +50,7 @@ function Content({ path }: { path: string }) {
<title>
{path === 'index.mdx' ? 'Talo - open source, self-hostable game backend' : page.title}
</title>
<link rel='canonical' href={`${siteOrigin}${url}`} />
<meta name='description' content={page.description} />
<DocsTitle>{page.title}</DocsTitle>
<DocsDescription>{page.description}</DocsDescription>
Expand All @@ -62,11 +65,11 @@ function Content({ path }: { path: string }) {
}

export default function Page({ loaderData }: Route.ComponentProps) {
const { path, pageTree } = useFumadocsLoader(loaderData)
const { path, url, pageTree } = useFumadocsLoader(loaderData)

return (
<DocsLayout {...baseOptions()} tree={pageTree}>
<Content path={path} />
<Content path={path} url={url} />
</DocsLayout>
)
}
9 changes: 0 additions & 9 deletions app/routes/intro-redirect.tsx

This file was deleted.

14 changes: 14 additions & 0 deletions app/routes/sitemap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { siteOrigin } from '@/lib/shared'
import { source } from '@/lib/source'

export function loader() {
const urls = source.getPages().map((page) => `<loc>${siteOrigin}${page.url}</loc>`)
const body = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urls.join('\n')}
</urlset>`

return new Response(body, {
headers: { 'content-type': 'application/xml; charset=utf-8' },
})
}
1 change: 1 addition & 0 deletions public/robots.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
User-agent: *
Disallow:
# Algolia-Crawler-Verif: 50BA364995958603
Sitemap: https://docs.trytalo.com/sitemap.xml
3 changes: 2 additions & 1 deletion react-router.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ export default {
const paths: string[] = []

for (const path of getStaticPaths()) {
// `/` navigates to the default version via the client component
if (path !== '/') {
paths.push(path)
}
Expand All @@ -21,6 +20,8 @@ export default {
paths.push(getUrl(slugs))
}

paths.push('/sitemap.xml')

return paths
},
} satisfies Config
15 changes: 15 additions & 0 deletions workers/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ type Env = {}
// Pre-versioning paths (e.g. /docs/godot/install) redirect to the default version.
const DEFAULT_VERSION = '1.x'
const LEGACY_SECTIONS = ['godot', 'unity', 'http', 'sockets', 'selfhosting', 'integrations']
const INTRO_SEGMENT = 'intro'
// React Router sets this while prerendering the SPA fallback during `pnpm build`.
// That request must render the shell, so it must skip the `/` redirect below.
const SPA_FALLBACK_HEADER = 'X-React-Router-SPA-Mode'

const requestHandler = createRequestHandler(
() => import('virtual:react-router/server-build'),
Expand All @@ -15,6 +19,14 @@ const requestHandler = createRequestHandler(
export default {
async fetch(request) {
const { pathname, origin } = new URL(request.url)
// `/` carries no version, so send it to the default one.
if (pathname === '/' && !request.headers.has(SPA_FALLBACK_HEADER)) {
return Response.redirect(`${origin}/${DEFAULT_VERSION}`, 301)
}
// `/intro` pre-dates the versioned paths and now lives at `/1.x`.
if (pathname === '/intro' || pathname === '/intro/') {
return Response.redirect(`${origin}/${DEFAULT_VERSION}`, 301)
}
// Old `/docs/*` URLs redirect to the prefix-less paths.
if (pathname === '/docs' || pathname === '/docs/') {
return Response.redirect(`${origin}/${DEFAULT_VERSION}`, 301)
Expand All @@ -23,6 +35,9 @@ export default {
if (match) {
const rest = match[1]
const [first] = rest.split('/')
if (first === INTRO_SEGMENT) {
return Response.redirect(`${origin}/${DEFAULT_VERSION}`, 301)
}
const target = LEGACY_SECTIONS.includes(first) ? `/${DEFAULT_VERSION}/${rest}` : `/${rest}`
return Response.redirect(`${origin}${target}`, 301)
}
Expand Down
4 changes: 4 additions & 0 deletions wrangler.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,9 @@
"observability": {
"enabled": true,
},
"assets": {
"html_handling": "drop-trailing-slash",
"run_worker_first": ["/"],
},
"main": "./workers/app.ts",
}
Loading