Add GA4 tag, robots.txt, and sitemap

This commit is contained in:
Haitao Pan 2026-01-14 17:41:08 +08:00
parent 6573a61746
commit 1b89c72c2e
3 changed files with 91 additions and 0 deletions

9
public/robots.txt Normal file
View File

@ -0,0 +1,9 @@
User-agent: *
Allow: /
Disallow: /admin/
Disallow: /api/
Disallow: /_next/
Disallow: /internal/
Sitemap: https://console.svc.plus/sitemap.xml

View File

@ -1,6 +1,7 @@
export const dynamic = 'error'
import './globals.css'
import Script from 'next/script'
import { AppProviders } from './AppProviders'
export const metadata = {
@ -10,10 +11,22 @@ export const metadata = {
const htmlAttributes = { lang: 'en' }
const bodyClassName = 'bg-[var(--color-background)] text-[var(--color-text)]'
const GA_ID = 'G-T4VM8G4Q42'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html {...htmlAttributes}>
<head>
<Script src={`https://www.googletagmanager.com/gtag/js?id=${GA_ID}`} strategy="afterInteractive" />
<Script id="gtag-init" strategy="afterInteractive">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${GA_ID}');
`}
</Script>
</head>
<body className={bodyClassName}>
<AppProviders>{children}</AppProviders>
</body>

69
src/app/sitemap.ts Normal file
View File

@ -0,0 +1,69 @@
import type { MetadataRoute } from 'next'
import { getBlogPosts } from '@/lib/blogContent'
import { getDocCollections } from '@/lib/docContent'
import { allWorkshops } from 'contentlayer/generated'
const baseUrl = 'https://console.svc.plus'
const staticEntries: MetadataRoute.Sitemap = [
{
url: `${baseUrl}/`,
changeFrequency: 'weekly',
priority: 1,
},
{
url: `${baseUrl}/blog`,
changeFrequency: 'weekly',
priority: 0.8,
},
{
url: `${baseUrl}/docs`,
changeFrequency: 'weekly',
priority: 0.8,
},
{
url: `${baseUrl}/download`,
changeFrequency: 'monthly',
priority: 0.7,
},
{
url: `${baseUrl}/services`,
changeFrequency: 'monthly',
priority: 0.6,
},
{
url: `${baseUrl}/workshop`,
changeFrequency: 'monthly',
priority: 0.6,
},
]
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const [posts, collections] = await Promise.all([getBlogPosts(), getDocCollections()])
const blogEntries: MetadataRoute.Sitemap = posts.map((post) => ({
url: `${baseUrl}/blog/${post.slug}`,
lastModified: post.date ? new Date(post.date) : undefined,
changeFrequency: 'weekly',
priority: 0.7,
}))
const docsEntries: MetadataRoute.Sitemap = collections.flatMap((collection) =>
collection.versions.map((version) => ({
url: `${baseUrl}/docs/${collection.slug}/${version.slug}`,
lastModified: version.updatedAt ? new Date(version.updatedAt) : undefined,
changeFrequency: 'monthly',
priority: 0.6,
})),
)
const workshopEntries: MetadataRoute.Sitemap = allWorkshops.map((workshop) => ({
url: `${baseUrl}/workshop/${workshop.slug}`,
lastModified: workshop.updatedAt ? new Date(workshop.updatedAt) : undefined,
changeFrequency: 'monthly',
priority: 0.6,
}))
return [...staticEntries, ...blogEntries, ...docsEntries, ...workshopEntries]
}