feat(website): add SEO landing pages for Claude Code, Codex, and OpenCode

Extract homepage into reusable LandingPage component with configurable
hero. Add /claude-code, /codex, and /opencode routes targeting
agent-specific mobile app search terms. Replace single-link footer
with four-column layout (Product, Agents, Community, Download).
This commit is contained in:
Mohamed Boudra
2026-03-15 11:16:28 +07:00
parent e80db346da
commit aa6c521394
6 changed files with 1245 additions and 1077 deletions
File diff suppressed because it is too large Load Diff
+63
View File
@@ -10,7 +10,10 @@
import { Route as rootRouteImport } from './routes/__root'
import { Route as PrivacyRouteImport } from './routes/privacy'
import { Route as OpencodeRouteImport } from './routes/opencode'
import { Route as DocsRouteImport } from './routes/docs'
import { Route as CodexRouteImport } from './routes/codex'
import { Route as ClaudeCodeRouteImport } from './routes/claude-code'
import { Route as ChangelogRouteImport } from './routes/changelog'
import { Route as IndexRouteImport } from './routes/index'
import { Route as DocsIndexRouteImport } from './routes/docs/index'
@@ -27,11 +30,26 @@ const PrivacyRoute = PrivacyRouteImport.update({
path: '/privacy',
getParentRoute: () => rootRouteImport,
} as any)
const OpencodeRoute = OpencodeRouteImport.update({
id: '/opencode',
path: '/opencode',
getParentRoute: () => rootRouteImport,
} as any)
const DocsRoute = DocsRouteImport.update({
id: '/docs',
path: '/docs',
getParentRoute: () => rootRouteImport,
} as any)
const CodexRoute = CodexRouteImport.update({
id: '/codex',
path: '/codex',
getParentRoute: () => rootRouteImport,
} as any)
const ClaudeCodeRoute = ClaudeCodeRouteImport.update({
id: '/claude-code',
path: '/claude-code',
getParentRoute: () => rootRouteImport,
} as any)
const ChangelogRoute = ChangelogRouteImport.update({
id: '/changelog',
path: '/changelog',
@@ -86,7 +104,10 @@ const DocsBestPracticesRoute = DocsBestPracticesRouteImport.update({
export interface FileRoutesByFullPath {
'/': typeof IndexRoute
'/changelog': typeof ChangelogRoute
'/claude-code': typeof ClaudeCodeRoute
'/codex': typeof CodexRoute
'/docs': typeof DocsRouteWithChildren
'/opencode': typeof OpencodeRoute
'/privacy': typeof PrivacyRoute
'/docs/best-practices': typeof DocsBestPracticesRoute
'/docs/cli': typeof DocsCliRoute
@@ -100,6 +121,9 @@ export interface FileRoutesByFullPath {
export interface FileRoutesByTo {
'/': typeof IndexRoute
'/changelog': typeof ChangelogRoute
'/claude-code': typeof ClaudeCodeRoute
'/codex': typeof CodexRoute
'/opencode': typeof OpencodeRoute
'/privacy': typeof PrivacyRoute
'/docs/best-practices': typeof DocsBestPracticesRoute
'/docs/cli': typeof DocsCliRoute
@@ -114,7 +138,10 @@ export interface FileRoutesById {
__root__: typeof rootRouteImport
'/': typeof IndexRoute
'/changelog': typeof ChangelogRoute
'/claude-code': typeof ClaudeCodeRoute
'/codex': typeof CodexRoute
'/docs': typeof DocsRouteWithChildren
'/opencode': typeof OpencodeRoute
'/privacy': typeof PrivacyRoute
'/docs/best-practices': typeof DocsBestPracticesRoute
'/docs/cli': typeof DocsCliRoute
@@ -130,7 +157,10 @@ export interface FileRouteTypes {
fullPaths:
| '/'
| '/changelog'
| '/claude-code'
| '/codex'
| '/docs'
| '/opencode'
| '/privacy'
| '/docs/best-practices'
| '/docs/cli'
@@ -144,6 +174,9 @@ export interface FileRouteTypes {
to:
| '/'
| '/changelog'
| '/claude-code'
| '/codex'
| '/opencode'
| '/privacy'
| '/docs/best-practices'
| '/docs/cli'
@@ -157,7 +190,10 @@ export interface FileRouteTypes {
| '__root__'
| '/'
| '/changelog'
| '/claude-code'
| '/codex'
| '/docs'
| '/opencode'
| '/privacy'
| '/docs/best-practices'
| '/docs/cli'
@@ -172,7 +208,10 @@ export interface FileRouteTypes {
export interface RootRouteChildren {
IndexRoute: typeof IndexRoute
ChangelogRoute: typeof ChangelogRoute
ClaudeCodeRoute: typeof ClaudeCodeRoute
CodexRoute: typeof CodexRoute
DocsRoute: typeof DocsRouteWithChildren
OpencodeRoute: typeof OpencodeRoute
PrivacyRoute: typeof PrivacyRoute
}
@@ -185,6 +224,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof PrivacyRouteImport
parentRoute: typeof rootRouteImport
}
'/opencode': {
id: '/opencode'
path: '/opencode'
fullPath: '/opencode'
preLoaderRoute: typeof OpencodeRouteImport
parentRoute: typeof rootRouteImport
}
'/docs': {
id: '/docs'
path: '/docs'
@@ -192,6 +238,20 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof DocsRouteImport
parentRoute: typeof rootRouteImport
}
'/codex': {
id: '/codex'
path: '/codex'
fullPath: '/codex'
preLoaderRoute: typeof CodexRouteImport
parentRoute: typeof rootRouteImport
}
'/claude-code': {
id: '/claude-code'
path: '/claude-code'
fullPath: '/claude-code'
preLoaderRoute: typeof ClaudeCodeRouteImport
parentRoute: typeof rootRouteImport
}
'/changelog': {
id: '/changelog'
path: '/changelog'
@@ -292,7 +352,10 @@ const DocsRouteWithChildren = DocsRoute._addFileChildren(DocsRouteChildren)
const rootRouteChildren: RootRouteChildren = {
IndexRoute: IndexRoute,
ChangelogRoute: ChangelogRoute,
ClaudeCodeRoute: ClaudeCodeRoute,
CodexRoute: CodexRoute,
DocsRoute: DocsRouteWithChildren,
OpencodeRoute: OpencodeRoute,
PrivacyRoute: PrivacyRoute,
}
export const routeTree = rootRouteImport
@@ -0,0 +1,25 @@
import { createFileRoute } from '@tanstack/react-router'
import { LandingPage } from '~/components/landing-page'
export const Route = createFileRoute('/claude-code')({
head: () => ({
meta: [
{ title: 'Claude Code Mobile App – Ship from your phone | Paseo' },
{
name: 'description',
content:
'Run Claude Code from your phone. Launch agents, check on progress, review diffs, and merge — all from your pocket. Self-hosted, your code stays on your machine.',
},
],
}),
component: ClaudeCodePage,
})
function ClaudeCodePage() {
return (
<LandingPage
title="Ship with Claude Code from your phone"
subtitle="Launch agents, check on progress, and merge from anywhere. Your Claude Code setup, your machine, your pocket."
/>
)
}
+25
View File
@@ -0,0 +1,25 @@
import { createFileRoute } from '@tanstack/react-router'
import { LandingPage } from '~/components/landing-page'
export const Route = createFileRoute('/codex')({
head: () => ({
meta: [
{ title: 'Codex Mobile App – Run Codex from anywhere | Paseo' },
{
name: 'description',
content:
'Run OpenAI Codex from your phone. Kick off agents, monitor progress, and ship code without being at your desk. Self-hosted, your code never leaves your machine.',
},
],
}),
component: CodexPage,
})
function CodexPage() {
return (
<LandingPage
title="Run Codex from anywhere"
subtitle="Kick off Codex agents on your machine from your phone. Check in on the train, review on the couch, merge from the park."
/>
)
}
File diff suppressed because it is too large Load Diff
+25
View File
@@ -0,0 +1,25 @@
import { createFileRoute } from '@tanstack/react-router'
import { LandingPage } from '~/components/landing-page'
export const Route = createFileRoute('/opencode')({
head: () => ({
meta: [
{ title: 'OpenCode Mobile App – Code from anywhere | Paseo' },
{
name: 'description',
content:
'Run OpenCode from your phone. Launch agents, watch them work, and ship code from wherever you are. Self-hosted, open source, your code stays local.',
},
],
}),
component: OpenCodePage,
})
function OpenCodePage() {
return (
<LandingPage
title="Run OpenCode from your phone"
subtitle="Launch agents, check on builds, and ship code from anywhere. Same setup, same machine, just not at your desk."
/>
)
}