Skip to content

Deployment

Deploy your Ardo documentation site to GitHub Pages, Netlify, Vercel, and more.

Ardo produces a fully static site out of the box. Your docs can stay in your repository, build in your CI pipeline, and deploy to any provider that serves files. When you run pnpm build, React Router prerenders every page to static HTML (via prerender: true in your react-router.config.ts), so no server is needed at runtime.

The build output is located in build/client/ and can be deployed to any static hosting provider.

GitHub Pages

Step 1: Configure Base Path and Basename

Ardo automatically detects your GitHub repository name from the git remote and sets Vite's base path for you. No manual base configuration is needed in vite.config.ts.

For client-side routing and prerendered HTML to work correctly under the subdirectory (e.g. https://username.github.io/my-docs/), wrap your React Router config with withArdoGitHubPages():

import type { Config } from "@react-router/dev/config"
import { withArdoGitHubPages } from "ardo/vite"

const config = {
  ssr: false,
  prerender: true,
} satisfies Config

export default withArdoGitHubPages(config)

withArdoGitHubPages() detects the repository name from your GitHub remote, sets React Router's basename, and registers Ardo's final synchronous flatten step for the React Router CLI build.

When React Router writes prerendered files under build/client/repo-name/, Ardo moves those files back to build/client/ after prerendering finishes. No post-build script is needed.

If you deploy to the root (https://username.github.io/), no configuration is needed — both base and basename will remain at their defaults.

For a GitHub Pages site behind a custom domain, disable GitHub Pages subpath detection and keep the React Router config unwrapped. The site is served from the domain root:

import { defineConfig } from "vite"
import { ardo } from "ardo/vite"

export default defineConfig({
  plugins: [
    ardo({
      title: "My Docs",
      siteUrl: "https://docs.example.com",
      githubPages: false,
    }),
  ],
})

Major-Versioned GitHub Pages Docs

For stable major-version URLs, build the current docs into a version folder and keep older major versions deployed as static folders:

/          -> static HTML redirect to /v3/
/v3/       -> current major docs
/v2/       -> previous major docs
/versions.json

Configure Ardo's versioning in vite.config.ts:

import { defineConfig } from "vite"
import { ardo } from "ardo/vite"

export default defineConfig({
  plugins: [
    ardo({
      title: "My Docs",
      siteUrl: "https://docs.example.com",
      versioning: {
        current: "v3",
        versions: [
          { id: "v3", label: "3.x", path: "/v3/" },
          { id: "v2", label: "2.x", path: "/v2/" },
        ],
      },
    }),
  ],
})

Set the matching React Router basename without GitHub Pages flattening:

import type { Config } from "@react-router/dev/config"
import { withArdoVersioning } from "ardo/vite"

const config = {
  ssr: false,
  prerender: true,
} satisfies Config

export default withArdoVersioning(config, { basename: "/v3/" })

The generated sitemap lists the current major version only. Older versions can stay available under their folders for stable inbound links, while the active build avoids advertising duplicate current content. On GitHub Pages, the root redirect is a static index.html file. If your custom domain sits behind a CDN or host that supports HTTP redirects, configure that provider-level redirect outside Ardo.

Step 2: Add a GitHub Actions Workflow

Create .github/workflows/deploy.yml in your repository:

name: Deploy to GitHub Pages

on:
  push:
    branches: [main]
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: "pages"
  cancel-in-progress: false

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup pnpm
        uses: pnpm/action-setup@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "22"
          cache: "pnpm"

      - name: Setup Pages
        uses: actions/configure-pages@v5

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Build
        run: pnpm build

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v4
        with:
          path: build/client

  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

Step 3: Enable GitHub Pages

In your repository settings, go to Pages and set the source to GitHub Actions.

Push to main and the workflow will build and deploy your site automatically.

If you use a custom domain, add it in the same Pages settings screen before updating DNS. For a custom GitHub Actions workflow, GitHub stores the custom domain in the repository settings; a CNAME file in the build output is not required.

Projects scaffolded with pnpm create ardo@latest include this workflow out of the box.

Netlify

Netlify requires no workflow file. Connect your Git repository in the Netlify dashboard and configure:

  • Build command: pnpm build
  • Publish directory: build/client

Netlify automatically detects the Node.js version from your package.json engines field or an .nvmrc file.

For subdirectory deployments, set base in vite.config.ts only when your Netlify site is served from a subpath. The GitHub Pages auto-detection above is specific to GitHub remotes and is not needed for the default Netlify root deployment.

Vercel

Connect your Git repository in the Vercel dashboard and configure:

  • Build command: pnpm build
  • Output directory: build/client
  • Framework preset: Other

Vercel handles routing and CDN configuration automatically.

Other Providers

Since Ardo outputs plain static files to build/client/, it works with any static hosting provider (Cloudflare Pages, AWS S3 + CloudFront, Firebase Hosting, etc.). Use pnpm build as the build command and build/client as the output directory.