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:
File diff suppressed because it is too large
Load Diff
@@ -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."
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -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
@@ -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."
|
||||
/>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user