From 48b80102e52b0660f35e622b9ca355fe9961f043 Mon Sep 17 00:00:00 2001 From: Gustavo Gonzalez Date: Mon, 13 Apr 2026 12:19:49 -0400 Subject: [PATCH] feat(seo): canonical tags, sitemap, robots, per-page OG images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the foundational SEO surface the docs site was missing: - Per-page , og:url, og:site_name, og:locale, and twitter:site injected via Vocs's native head({ path }) hook. - Dynamic per-page OG images via Vocs's hosted API (ogImageUrl, object form — the string form short-circuits in useOgImageUrl on v1.4.1). - baseUrl wired to the existing siteUrl chain so Vocs emits and resolves %logo for OG image rendering. - iconUrl set so ships in . - sitemap.xml + robots.txt generated by extending the existing post-build walker in scripts/substitute-site-url.mjs. Previews emit Disallow: / and every page gets noindex so Vercel preview URLs never compete with production in search. - Homepage H1/title rewritten so titleTemplate no longer produces the broken "Taiko - Taiko" tag, and 13 short meta descriptions rewritten from 40–80 characters to 140–160 with primary keywords. Renames vocs.config.ts -> vocs.config.tsx because head({ path }) uses JSX. Updates the lone tsconfig.json + site-url.mjs references. Verified locally on both prod (VERCEL_ENV=production) and preview builds: canonical + og:image + robots + sitemap all emit correctly per environment. Co-Authored-By: Claude Opus 4.6 (1M context) --- docs/pages/guides/bridge-tokens.mdx | 2 +- docs/pages/guides/run-a-node.mdx | 2 +- docs/pages/index.mdx | 4 +-- docs/pages/network/software-releases.mdx | 2 +- docs/pages/protocol/based-rollups.mdx | 2 +- docs/pages/protocol/bridging.mdx | 2 +- docs/pages/protocol/economics.mdx | 2 +- docs/pages/protocol/overview.mdx | 2 +- docs/pages/protocol/preconfirmations.mdx | 2 +- docs/pages/protocol/proving-system.mdx | 2 +- docs/pages/quickstart/deploy.mdx | 2 +- docs/pages/resources/developer-tools.mdx | 2 +- docs/pages/resources/faq.mdx | 2 +- scripts/site-url.mjs | 2 +- scripts/substitute-site-url.mjs | 44 +++++++++++++++++++++--- tsconfig.json | 2 +- vocs.config.ts => vocs.config.tsx | 32 +++++++++++++++++ 17 files changed, 87 insertions(+), 21 deletions(-) rename vocs.config.ts => vocs.config.tsx (74%) diff --git a/docs/pages/guides/bridge-tokens.mdx b/docs/pages/guides/bridge-tokens.mdx index 33dac47..5b72dcf 100644 --- a/docs/pages/guides/bridge-tokens.mdx +++ b/docs/pages/guides/bridge-tokens.mdx @@ -1,4 +1,4 @@ -# Bridge Tokens [Move tokens between Ethereum and Taiko.] +# Bridge Tokens [Bridge ETH and ERC-20 tokens between Ethereum L1 and Taiko L2 programmatically. Vault contracts, message proofs, and claim-side execution.] Most users should bridge through the official web UI. The programmatic flow below is for scripts and AI agents. diff --git a/docs/pages/guides/run-a-node.mdx b/docs/pages/guides/run-a-node.mdx index 3ac4622..6c5d39f 100644 --- a/docs/pages/guides/run-a-node.mdx +++ b/docs/pages/guides/run-a-node.mdx @@ -1,4 +1,4 @@ -# Run a Node [Run a Taiko node using Docker or from source.] +# Run a Node [Run a Taiko mainnet or Hoodi testnet node with Docker or from source. Hardware, sync modes, RPC exposure, and taiko-client setup.] ## Architecture diff --git a/docs/pages/index.mdx b/docs/pages/index.mdx index 120e5b5..4017736 100644 --- a/docs/pages/index.mdx +++ b/docs/pages/index.mdx @@ -1,8 +1,8 @@ --- -description: Documentation, guides, and protocol specifications for Taiko. +description: Taiko developer documentation — guides, protocol specs, and network reference for the based rollup on Ethereum. Deploy contracts, bridge tokens, and run a node. --- -# Taiko [Documentation, guides, and protocol specifications] +# Taiko Documentation [Guides, protocol specs, and network reference for Taiko, a based rollup on Ethereum. Deploy contracts, bridge tokens, and run a node.] ## Welcome to Taiko! diff --git a/docs/pages/network/software-releases.mdx b/docs/pages/network/software-releases.mdx index a664a60..d79707b 100644 --- a/docs/pages/network/software-releases.mdx +++ b/docs/pages/network/software-releases.mdx @@ -1,4 +1,4 @@ -# Software Releases [Software releases and deployments for Taiko components.] +# Software Releases [Latest release versions for Taiko protocol contracts, taiko-geth, taiko-client, simple-taiko-node, and raiko — with links to changelogs.] ## Software Releases diff --git a/docs/pages/protocol/based-rollups.mdx b/docs/pages/protocol/based-rollups.mdx index d45bc82..ff9bf31 100644 --- a/docs/pages/protocol/based-rollups.mdx +++ b/docs/pages/protocol/based-rollups.mdx @@ -1,4 +1,4 @@ -# Based Rollups [How based rollup sequencing works.] +# Based Rollups [How based rollup sequencing works — Ethereum L1 validators order L2 transactions, eliminating centralized sequencers while inheriting Ethereum security.] A **based rollup** is a rollup whose block sequencing is driven by the underlying L1 chain rather than a separate sequencer. In Taiko's case, Ethereum L1 validators determine the ordering of L2 blocks. This design eliminates the need for a centralized sequencer and makes the rollup a natural extension of Ethereum. diff --git a/docs/pages/protocol/bridging.mdx b/docs/pages/protocol/bridging.mdx index 0a8324c..c80b58a 100644 --- a/docs/pages/protocol/bridging.mdx +++ b/docs/pages/protocol/bridging.mdx @@ -1,4 +1,4 @@ -# Bridging [Cross-chain messaging between Ethereum and Taiko.] +# Bridging [Trust-minimized cross-chain messaging and asset transfers between Ethereum and Taiko using Merkle proofs, signal service, and synchronized state roots.] Taiko's bridge enables **trust-minimized asset transfers and message passing** between Ethereum (L1) and Taiko (L2). The bridge uses Merkle proofs and synchronized world state roots to verify cross-chain messages, requiring no trusted third party. Any contract or user can send and verify messages between chains. diff --git a/docs/pages/protocol/economics.mdx b/docs/pages/protocol/economics.mdx index 83abbd2..ef7448b 100644 --- a/docs/pages/protocol/economics.mdx +++ b/docs/pages/protocol/economics.mdx @@ -1,4 +1,4 @@ -# Economics [Fees, bonds, and token economics on Taiko.] +# Economics [Taiko fee flow, proposer and prover bonds, TAIKO token utility, and DAO treasury mechanics — the economic model behind the based rollup.] Taiko's economic model ensures fair compensation for the actors who operate the network -- proposers and provers -- while sustaining long-term protocol development through the Taiko DAO Treasury. The model is designed around the based rollup architecture, where fees flow through a transparent on-chain cycle. diff --git a/docs/pages/protocol/overview.mdx b/docs/pages/protocol/overview.mdx index 6539215..ae5465e 100644 --- a/docs/pages/protocol/overview.mdx +++ b/docs/pages/protocol/overview.mdx @@ -1,4 +1,4 @@ -# Protocol Overview [What is Taiko and how does it work.] +# Protocol Overview [How Taiko works — a type-1 ZK-EVM based rollup that inherits Ethereum sequencing, with multi-proof verification and L1-anchored finality.] Taiko is an **Ethereum-equivalent (type-1) based rollup** that scales Ethereum without compromising its core properties: censorship resistance, permissionless access, and decentralization. Unlike traditional rollups that rely on centralized sequencers, Taiko delegates block sequencing to Ethereum L1 validators, making it a natural extension of Ethereum itself. diff --git a/docs/pages/protocol/preconfirmations.mdx b/docs/pages/protocol/preconfirmations.mdx index dcf1c7f..bcf90c6 100644 --- a/docs/pages/protocol/preconfirmations.mdx +++ b/docs/pages/protocol/preconfirmations.mdx @@ -1,4 +1,4 @@ -# Preconfirmations [Based preconfirmations on Taiko.] +# Preconfirmations [Sub-second transaction inclusion guarantees on Taiko from a designated preconfer, backed by the L1 proposal pipeline and forced inclusion.] Based preconfirmations give users **early transaction inclusion guarantees** without abandoning based rollup principles. A designated preconfer sequences blocks off-chain and gossips them to the network, providing users with near-instant transaction receipts. The preconfer then proposes the sequenced blocks on-chain to Ethereum L1, preserving Taiko's status as a based rollup. diff --git a/docs/pages/protocol/proving-system.mdx b/docs/pages/protocol/proving-system.mdx index 51a121c..6503e12 100644 --- a/docs/pages/protocol/proving-system.mdx +++ b/docs/pages/protocol/proving-system.mdx @@ -1,4 +1,4 @@ -# Proving System [Taiko's Shasta proving and verification flow.] +# Proving System [Taiko's Shasta proving lifecycle — Inbox proposals, SGX and ZK multi-proof verification, and checkpoint-driven L1 finalization for L2 state.] Under the **Shasta** architecture, Taiko proves L2 state transitions on Ethereum L1 through the `Inbox` and a compose `proofVerifier`. The core idea is still proof diversity, but the lifecycle is no longer the old Pacaya-style `proveBatches` plus `verifyBatches` flow. In Shasta, a successful proof submission advances finalization directly for a contiguous range of proposals. diff --git a/docs/pages/quickstart/deploy.mdx b/docs/pages/quickstart/deploy.mdx index bf280db..4edcf26 100644 --- a/docs/pages/quickstart/deploy.mdx +++ b/docs/pages/quickstart/deploy.mdx @@ -1,4 +1,4 @@ -# Deploy a Contract [Deploy and verify smart contracts on Taiko using Foundry.] +# Deploy a Contract [Deploy and verify Solidity smart contracts on Taiko mainnet with Foundry. Shanghai EVM profile, Etherscan V2 verification, end-to-end.] ## Prompt mode diff --git a/docs/pages/resources/developer-tools.mdx b/docs/pages/resources/developer-tools.mdx index efdbd28..766a27c 100644 --- a/docs/pages/resources/developer-tools.mdx +++ b/docs/pages/resources/developer-tools.mdx @@ -1,4 +1,4 @@ -# Developer Tools [Tools and resources for building on Taiko.] +# Developer Tools [Block explorers, RPC endpoints, bridge, faucets, indexers, and SDKs for building on Taiko mainnet and Hoodi testnet.] ## Block Explorers diff --git a/docs/pages/resources/faq.mdx b/docs/pages/resources/faq.mdx index cb54bd0..a1c3be2 100644 --- a/docs/pages/resources/faq.mdx +++ b/docs/pages/resources/faq.mdx @@ -1,4 +1,4 @@ -# FAQ [Frequently asked questions about Taiko.] +# FAQ [Answers to common questions about Taiko — based sequencing, type-1 EVM equivalence, fees, bridging, proving, and how to get started as a developer.] ## General FAQ diff --git a/scripts/site-url.mjs b/scripts/site-url.mjs index bcd94cb..395af33 100644 --- a/scripts/site-url.mjs +++ b/scripts/site-url.mjs @@ -1,4 +1,4 @@ -// Shared site-URL resolution for vocs.config.ts (dev + Vite transform) and +// Shared site-URL resolution for vocs.config.tsx (dev + Vite transform) and // scripts/substitute-site-url.mjs (post-build pass over dist/). // // Chain: explicit SITE_URL override → Vercel production alias → Vercel branch diff --git a/scripts/substitute-site-url.mjs b/scripts/substitute-site-url.mjs index a77f2ba..d60a157 100644 --- a/scripts/substitute-site-url.mjs +++ b/scripts/substitute-site-url.mjs @@ -1,7 +1,10 @@ -// Post-build pass that replaces every __SITE_URL__ sentinel in the build -// output with the resolved siteUrl. Runs after `vocs build` fully exits, -// so it catches files written by Vite's transform pipeline, Vocs's llms -// plugin (.md/.txt exports), and Vite's public-dir copy (docs/public/SKILL.md). +// Post-build pass that: +// 1. Replaces every __SITE_URL__ sentinel in the build output with the +// resolved siteUrl (catches Vite's public-dir copies, Vocs's .md/.txt +// exports, and pre-rendered HTML). +// 2. Emits sitemap.xml + robots.txt so search engines can crawl and index +// the site. Non-production builds get a Disallow-all robots so Vercel +// previews never compete with the production domain. // // Vocs picks the output directory based on whether it detects Vercel: // - Local / CI outside Vercel: docs/dist @@ -9,7 +12,7 @@ // // See node_modules/vocs/_lib/vite/utils/resolveOutDir.js. import { existsSync, readFileSync, readdirSync, statSync, writeFileSync } from 'node:fs' -import { join } from 'node:path' +import { join, relative, sep } from 'node:path' import { siteUrl } from './site-url.mjs' const outDir = process.env.VERCEL ? '.vercel/output/static' : 'docs/dist' @@ -20,6 +23,7 @@ if (!existsSync(outDir)) { const textExts = new Set(['.md', '.txt', '.json', '.html', '.js']) let replaced = 0 +const htmlRoutes = [] const walk = (dir) => { for (const entry of readdirSync(dir)) { const full = join(dir, entry) @@ -27,6 +31,10 @@ const walk = (dir) => { walk(full) continue } + if (entry === 'index.html') { + const rel = relative(outDir, full).split(sep).slice(0, -1).join('/') + htmlRoutes.push(rel ? `/${rel}` : '/') + } const dot = entry.lastIndexOf('.') if (dot < 0 || !textExts.has(entry.slice(dot))) continue const contents = readFileSync(full, 'utf8') @@ -38,3 +46,29 @@ const walk = (dir) => { walk(outDir) console.log(`[site-url] rewrote ${replaced} files in ${outDir} with ${siteUrl}`) + +// --- sitemap.xml + robots.txt -------------------------------------------- +const isProd = process.env.VERCEL_ENV === 'production' +const lastmod = new Date().toISOString().slice(0, 10) + +const sitemap = + `\n` + + `\n` + + htmlRoutes + .sort() + .map( + (route) => + ` ${siteUrl}${route}${lastmod}`, + ) + .join('\n') + + `\n\n` + +const robots = isProd + ? `User-agent: *\nAllow: /\n\nSitemap: ${siteUrl}/sitemap.xml\n` + : `User-agent: *\nDisallow: /\n` + +writeFileSync(join(outDir, 'sitemap.xml'), sitemap) +writeFileSync(join(outDir, 'robots.txt'), robots) +console.log( + `[site-url] wrote sitemap.xml (${htmlRoutes.length} urls) and robots.txt (${isProd ? 'prod' : 'preview'})`, +) diff --git a/tsconfig.json b/tsconfig.json index 9482947..940cf31 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,5 +8,5 @@ "esModuleInterop": true, "skipLibCheck": true }, - "include": ["docs/**/*.ts", "docs/**/*.tsx", "vocs.config.ts"] + "include": ["docs/**/*.ts", "docs/**/*.tsx", "vocs.config.tsx"] } diff --git a/vocs.config.ts b/vocs.config.tsx similarity index 74% rename from vocs.config.ts rename to vocs.config.tsx index 2382a25..d7e1f1c 100644 --- a/vocs.config.ts +++ b/vocs.config.tsx @@ -1,12 +1,21 @@ +import * as React from 'react' import { defineConfig } from 'vocs' import { siteUrl } from './scripts/site-url.mjs' +// Vercel previews and local builds emit `noindex` so they don't compete with +// the production domain in search. +const isProdBuild = process.env.VERCEL_ENV === 'production' + export default defineConfig({ title: 'Taiko Docs', titleTemplate: '%s - Taiko', description: 'Documentation for Taiko, a based rollup on Ethereum', + // Vocs populates from this and uses it as %logo in the OG image API. + baseUrl: siteUrl, + logoUrl: { dark: '/logo-dark.svg', light: '/logo-light.svg' }, + iconUrl: '/favicon.svg', theme: { accentColor: { light: '#e81899', dark: '#fc5cb5' }, @@ -24,6 +33,29 @@ export default defineConfig({ google: 'Public Sans', }, + // Vocs-hosted dynamic OG image API: renders per-page social cards using + // each page's title + description. Object form (not string form) because + // Vocs's useOgImageUrl short-circuits on strings in v1.4.1. + ogImageUrl: { + '/': 'https://vocs.dev/api/og?logo=%logo&title=%title&description=%description', + }, + + // Per-page : canonical + og:url + twitter completion. Previews get + // noindex so they never outrank production. + head({ path }) { + const url = `${siteUrl}${path}` + return ( + <> + + + + + + {!isProdBuild && } + + ) + }, + socials: [ { icon: 'github', link: 'https://github.com/taikoxyz' }, { icon: 'discord', link: 'https://discord.com/invite/taiko-984015101017346058' },