跳至主要內容

    SSG

    SSG 在建置時就把每條路徑產出 HTML,速度快、成本低、可索引性高,是內容型網站的強力選項。

    定義

    SSG(Static Site Generation)在 build 時把頁面渲染成靜態 HTML 檔案。部署後不需要每次請求都跑伺服器渲染,通常在 CDN 上就能極快回應,非常適合教學、部落格、詞彙表與工具介紹等內容頁。

    為什麼重要

    • 效能最好:CDN 直接回傳 HTML,TTFB 極低(通常 < 50ms)
    • SEO 友善:每路徑都有可索引 HTML,不依賴 JavaScript 執行
    • 部署簡單:靜態站點非常適合 Cloudflare Pages、Vercel、Netlify
    • 成本最低:不需要伺服器運算,只有 CDN 流量費用
    • 可靠性高:沒有伺服器故障風險,CDN 有多層冗餘
    • 支援增量更新:ISR(Next.js)或 on-demand rebuild 可局部更新
    • 利於 AI 引擎索引:ChatGPT/Perplexity 的爬蟲渲染能力有限,靜態 HTML 最可靠

    怎麼做(實作重點)

    • 把可靜態化的頁面在 build 期 prerender(如詞彙表、教學、工具頁)
    • 確保每頁 meta/canonical/hreflang/schema 都是 route-aware
    • 內容更新後重新 build/deploy,並更新 sitemap
    • 使用 ISR 或 webhook 觸發增量建置,減少完整 rebuild 時間
    • 設定 CDN 快取策略:immutable for hashed assets, s-maxage for HTML
    • 建立 prerender 路由清單:從 CMS 或 JSON 自動產生需 prerender 的路徑
    • 驗證 SSG 輸出:確保每個 HTML 檔案都有完整 head 與結構化資料

    範例

    typescript
    // scripts/prerender.ts
    import { renderToString } from 'react-dom/server';
    import { StaticRouter } from 'react-router-dom/server';
    import fs from 'fs';
    import path from 'path';
    import App from '../src/App';
    import glossary from '../src/content/glossary.json';
    
    // 從 JSON 產生路由清單
    const routes = [
      '/',
      '/glossary',
      ...glossary.terms.map(t => `/glossary/${t.slug}`),
      ...glossary.terms.map(t => `/en/glossary/${t.slug}`),
    ];
    
    const template = fs.readFileSync('dist/index.html', 'utf-8');
    
    for (const route of routes) {
      const html = renderToString(
        <StaticRouter location={route}><App /></StaticRouter>
      );
      const output = template.replace('<!--ssr-outlet-->', html);
      const dir = `dist${route}`;
      fs.mkdirSync(dir, { recursive: true });
      fs.writeFileSync(path.join(dir, 'index.html'), output);
      console.log(`Prerendered: ${route}`);
    }
    typescript
    // astro.config.mjs
    import { defineConfig } from 'astro/config';
    import react from '@astrojs/react';
    import sitemap from '@astrojs/sitemap';
    
    export default defineConfig({
      site: 'https://developer-seo-hub.com',
      integrations: [
        react(),
        sitemap(), // 自動產生 sitemap.xml
      ],
      output: 'static', // 純 SSG 模式
      build: {
        // 為 hashed assets 設定長期快取
        assets: '_astro',
      },
    });
    
    // src/pages/glossary/[slug].astro
    ---
    import { getCollection } from 'astro:content';
    export async function getStaticPaths() {
      const terms = await getCollection('glossary');
      return terms.map(term => ({
        params: { slug: term.slug },
        props: { term },
      }));
    }
    const { term } = Astro.props;
    ---
    <html><head><title>{term.data.title}</title></head>...</html>

    相關連結

    常見問題

    關於這個詞彙的常見問答。

    回到詞彙表