feat(website): basic SEO
This commit is contained in:
4
packages/website/public/robots.txt
Normal file
4
packages/website/public/robots.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
Sitemap: https://alibaba.github.io/page-agent/sitemap.xml
|
||||
9
packages/website/src/lib/useDocumentTitle.ts
Normal file
9
packages/website/src/lib/useDocumentTitle.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { useEffect } from 'react'
|
||||
|
||||
const DEFAULT_TITLE = 'PageAgent - The GUI Agent Living in Your Webpage'
|
||||
|
||||
export function useDocumentTitle(title?: string) {
|
||||
useEffect(() => {
|
||||
document.title = title ? `${title} - PageAgent` : DEFAULT_TITLE
|
||||
}, [title])
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import { Link, useLocation } from 'wouter'
|
||||
|
||||
import { SparklesText } from '@/components/ui/sparkles-text'
|
||||
import { useLanguage } from '@/i18n/context'
|
||||
import { useDocumentTitle } from '@/lib/useDocumentTitle'
|
||||
|
||||
interface DocsLayoutProps {
|
||||
children: ReactNode
|
||||
@@ -65,6 +66,12 @@ export default function DocsLayout({ children }: DocsLayoutProps) {
|
||||
},
|
||||
]
|
||||
|
||||
const activeTitle = navigationSections
|
||||
.flatMap((s) => s.items)
|
||||
.find((item) => item.path === location)?.title
|
||||
|
||||
useDocumentTitle(activeTitle)
|
||||
|
||||
return (
|
||||
<div className="max-w-7xl mx-auto px-6 py-8 overflow-x-auto">
|
||||
<div className="flex gap-8 min-w-225">
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { Suspense, lazy } from 'react'
|
||||
|
||||
import { useDocumentTitle } from '@/lib/useDocumentTitle'
|
||||
|
||||
import HeroSection from './HeroSection'
|
||||
|
||||
const FeaturesSection = lazy(() => import('./FeaturesSection'))
|
||||
@@ -7,6 +9,8 @@ const ScenariosSection = lazy(() => import('./ScenariosSection'))
|
||||
const OneMoreThingSection = lazy(() => import('./OneMoreThingSection'))
|
||||
|
||||
export default function HomePage() {
|
||||
useDocumentTitle()
|
||||
|
||||
return (
|
||||
<>
|
||||
<HeroSection />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import tailwindcss from '@tailwindcss/vite'
|
||||
import react from '@vitejs/plugin-react-swc'
|
||||
import { config as dotenvConfig } from 'dotenv'
|
||||
import { copyFileSync, mkdirSync, readFileSync } from 'node:fs'
|
||||
import { copyFileSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
|
||||
import process from 'node:process'
|
||||
import { dirname, join, resolve } from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
@@ -35,6 +35,8 @@ const SPA_ROUTES = [
|
||||
'docs/advanced/security-permissions',
|
||||
]
|
||||
|
||||
const SITE_URL = 'https://alibaba.github.io/page-agent'
|
||||
|
||||
function spaRoutes() {
|
||||
return {
|
||||
name: 'spa-routes',
|
||||
@@ -47,6 +49,19 @@ function spaRoutes() {
|
||||
copyFileSync(src, join(dir, 'index.html'))
|
||||
}
|
||||
console.log(` ✓ Copied index.html to ${SPA_ROUTES.length} SPA routes`)
|
||||
|
||||
const today = new Date().toISOString().split('T')[0]
|
||||
const urls = ['', ...SPA_ROUTES]
|
||||
.map(
|
||||
(route) =>
|
||||
` <url>\n <loc>${SITE_URL}/${route}</loc>\n <lastmod>${today}</lastmod>\n </url>`
|
||||
)
|
||||
.join('\n')
|
||||
writeFileSync(
|
||||
join(dist, 'sitemap.xml'),
|
||||
`<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n${urls}\n</urlset>\n`
|
||||
)
|
||||
console.log(` ✓ Generated sitemap.xml with ${SPA_ROUTES.length + 1} URLs`)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user