Skip to content

Deployment

After building your Rspress documentation site, the next step is deploying it to make it accessible to users. This chapter covers deployment strategies for popular platforms and best practices.

Deployment Overview

What Gets Deployed?

After running npm run build, you'll have static files ready for deployment:

doc_build/
├── index.html
├── guide/
│   └── *.html
├── api/
│   └── *.html
├── assets/
│   ├── chunks/
│   ├── css/
│   └── images/
└── _rspress/

These are pure static files that can be hosted anywhere.

Deployment Options

  • Static Hosting: Vercel, Netlify, GitHub Pages, Cloudflare Pages
  • Traditional Hosting: Apache, Nginx, AWS S3
  • CDN: CloudFront, Fastly, Akamai
  • Container: Docker, Kubernetes

Vercel Deployment

Quick Deploy

Deploy to Vercel with one command:

bash
# Install Vercel CLI
npm install -g vercel

# Deploy
vercel

# Follow prompts to configure and deploy

GitHub Integration

  1. Push to GitHub:
bash
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/username/repo.git
git push -u origin main
  1. Connect to Vercel:
  • Visit vercel.com
  • Click "Import Project"
  • Select your repository
  • Configure build settings:
    • Build Command: npm run build
    • Output Directory: doc_build
    • Install Command: npm install
  1. Deploy:
  • Vercel automatically deploys on push
  • Preview deployments for pull requests
  • Production deployment from main branch

Vercel Configuration

Create vercel.json:

json
{
  "buildCommand": "npm run build",
  "outputDirectory": "doc_build",
  "devCommand": "npm run dev",
  "installCommand": "npm install",
  "framework": null,
  "cleanUrls": true,
  "trailingSlash": false,
  "headers": [
    {
      "source": "/assets/(.*)",
      "headers": [
        {
          "key": "Cache-Control",
          "value": "public, max-age=31536000, immutable"
        }
      ]
    }
  ],
  "rewrites": [
    {
      "source": "/(.*)",
      "destination": "/index.html"
    }
  ]
}

Netlify Deployment

Drag and Drop

Simplest method for quick deployment:

  1. Build your site: npm run build
  2. Go to netlify.com
  3. Drag doc_build folder to deploy zone
  4. Site is live!

Git Integration

  1. Push to Git Repository (GitHub, GitLab, Bitbucket)

  2. Connect to Netlify:

  • Sign in to Netlify
  • Click "New site from Git"
  • Choose your repository
  • Configure:
    • Build command: npm run build
    • Publish directory: doc_build
  1. Deploy:
  • Automatic deploys on push
  • Deploy previews for PRs
  • Rollback capability

Netlify Configuration

Create netlify.toml:

toml
[build]
  command = "npm run build"
  publish = "doc_build"

[build.environment]
  NODE_VERSION = "18"

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

[[headers]]
  for = "/assets/*"
  [headers.values]
    Cache-Control = "public, max-age=31536000, immutable"

[[headers]]
  for = "/*.html"
  [headers.values]
    Cache-Control = "public, max-age=0, must-revalidate"

Netlify Functions

Add serverless functions if needed:

javascript
// netlify/functions/api.js
exports.handler = async (event, context) => {
  return {
    statusCode: 200,
    body: JSON.stringify({ message: 'Hello from Netlify!' }),
  };
};

GitHub Pages

GitHub Actions Deployment

Create .github/workflows/deploy.yml:

yaml
name: Deploy to GitHub Pages

on:
  push:
    branches: [main]

# Sets permissions of the GITHUB_TOKEN
permissions:
  contents: read
  pages: write
  id-token: write

# Allow one concurrent deployment
concurrency:
  group: "pages"
  cancel-in-progress: true

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

      - name: Setup Node
        uses: actions/setup-node@v3
        with:
          node-version: 18
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Build
        run: npm run build
        env:
          NODE_ENV: production

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v2
        with:
          path: ./doc_build

  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@v2

Configuration for GitHub Pages

Configure base path if deploying to repository path:

typescript
// rspress.config.ts
export default defineConfig({
  base: '/repository-name/',  // For username.github.io/repository-name
  // base: '/',               // For username.github.io
});

Enable GitHub Pages

  1. Go to repository Settings
  2. Navigate to Pages section
  3. Select "GitHub Actions" as source
  4. Push to main branch to trigger deployment

Cloudflare Pages

Wrangler CLI

bash
# Install Wrangler
npm install -g wrangler

# Login to Cloudflare
wrangler login

# Deploy
wrangler pages publish doc_build

Git Integration

  1. Connect Repository:
  • Sign in to Cloudflare Dashboard
  • Go to Pages
  • Click "Create a project"
  • Connect GitHub/GitLab repository
  1. Build Settings:
Build command: npm run build
Build output directory: doc_build
Root directory: /
  1. Environment Variables (if needed):
NODE_VERSION=18

Cloudflare Configuration

Create wrangler.toml:

toml
name = "my-rspress-site"
type = "webpack"
account_id = "your-account-id"

[site]
bucket = "./doc_build"

[build]
command = "npm run build"

AWS S3 + CloudFront

S3 Bucket Setup

bash
# Install AWS CLI
npm install -g aws-cli

# Configure AWS credentials
aws configure

# Create S3 bucket
aws s3 mb s3://my-docs-site

# Enable static website hosting
aws s3 website s3://my-docs-site/ \
  --index-document index.html \
  --error-document 404.html

# Upload files
npm run build
aws s3 sync doc_build/ s3://my-docs-site/ \
  --delete \
  --cache-control "public, max-age=31536000" \
  --exclude "*.html" \
  --exclude "sitemap.xml"

# Upload HTML with different cache
aws s3 sync doc_build/ s3://my-docs-site/ \
  --delete \
  --cache-control "public, max-age=0, must-revalidate" \
  --exclude "*" \
  --include "*.html" \
  --include "sitemap.xml"

CloudFront Distribution

  1. Create CloudFront distribution
  2. Origin: S3 bucket website endpoint
  3. Configure caching:
    • Default TTL: 86400 (1 day)
    • HTML files: 0 (always revalidate)
    • Assets: 31536000 (1 year)

Automated Deployment

Create deployment script:

bash
#!/bin/bash
# deploy.sh

echo "Building site..."
npm run build

echo "Uploading to S3..."
aws s3 sync doc_build/ s3://my-docs-site/ --delete

echo "Invalidating CloudFront cache..."
aws cloudfront create-invalidation \
  --distribution-id YOUR_DISTRIBUTION_ID \
  --paths "/*"

echo "Deployment complete!"

Docker Deployment

Dockerfile

dockerfile
# Build stage
FROM node:18-alpine AS builder

WORKDIR /app

COPY package*.json ./
RUN npm ci

COPY . .
RUN npm run build

# Production stage
FROM nginx:alpine

COPY --from=builder /app/doc_build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

Nginx Configuration

nginx
# nginx.conf
server {
    listen 80;
    server_name localhost;
    root /usr/share/nginx/html;
    index index.html;

    # Gzip compression
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    # Cache static assets
    location /assets/ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # Handle client-side routing
    location / {
        try_files $uri $uri/ /index.html;
    }

    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
}

Build and Run

bash
# Build image
docker build -t my-docs .

# Run container
docker run -d -p 8080:80 my-docs

# Visit http://localhost:8080

Custom Server Deployment

Node.js Server

javascript
// server.js
const express = require('express');
const path = require('path');

const app = express();
const PORT = process.env.PORT || 3000;

// Serve static files
app.use(express.static(path.join(__dirname, 'doc_build'), {
  maxAge: '1y',
  etag: true,
}));

// Handle client-side routing
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'doc_build', 'index.html'));
});

app.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}`);
});

Apache Configuration

apache
# .htaccess
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /

  # Handle client-side routing
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>

# Cache control
<IfModule mod_headers.c>
  <FilesMatch "\.(html|xml)$">
    Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
  </FilesMatch>

  <FilesMatch "\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2)$">
    Header set Cache-Control "max-age=31536000, public, immutable"
  </FilesMatch>
</IfModule>

Deployment Optimization

Build Optimization

typescript
// rspress.config.ts
export default defineConfig({
  builderConfig: {
    output: {
      minify: true,
      cleanDistPath: true,
    },
    performance: {
      chunkSplit: {
        strategy: 'split-by-experience',
      },
      preload: true,
      prefetch: true,
    },
  },
});

Compression

Enable Gzip/Brotli compression:

bash
# Pre-compress files
npm install -g gzipper

# Gzip compression
gzipper compress ./doc_build

# Brotli compression
gzipper compress ./doc_build --brotli

CDN Integration

Use CDN for assets:

typescript
export default defineConfig({
  builderConfig: {
    output: {
      assetPrefix: 'https://cdn.example.com/',
    },
  },
});

Environment-specific Builds

Multiple Environments

json
// package.json
{
  "scripts": {
    "build": "rspress build",
    "build:staging": "NODE_ENV=staging rspress build",
    "build:production": "NODE_ENV=production rspress build"
  }
}

Environment Configuration

typescript
// rspress.config.ts
const isProd = process.env.NODE_ENV === 'production';

export default defineConfig({
  base: isProd ? '/' : '/staging/',
  head: [
    ['meta', { name: 'robots', content: isProd ? 'index,follow' : 'noindex,nofollow' }],
  ],
});

Monitoring and Analytics

Google Analytics

typescript
export default defineConfig({
  head: [
    [
      'script',
      {
        async: true,
        src: 'https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID',
      },
    ],
    [
      'script',
      {},
      `
        window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        gtag('js', new Date());
        gtag('config', 'GA_MEASUREMENT_ID');
      `,
    ],
  ],
});

Error Tracking

typescript
// Add error tracking (e.g., Sentry)
export default defineConfig({
  head: [
    [
      'script',
      {
        src: 'https://browser.sentry-cdn.com/7.x.x/bundle.min.js',
        crossorigin: 'anonymous',
      },
    ],
    [
      'script',
      {},
      `
        Sentry.init({
          dsn: 'YOUR_SENTRY_DSN',
          environment: 'production',
        });
      `,
    ],
  ],
});

Deployment Checklist

Before deploying:

  • [ ] Run npm run build successfully
  • [ ] Test with npm run preview
  • [ ] Verify all pages load correctly
  • [ ] Check responsive design on mobile
  • [ ] Test all internal links
  • [ ] Validate HTML
  • [ ] Check Lighthouse scores
  • [ ] Configure proper caching headers
  • [ ] Set up HTTPS/SSL
  • [ ] Configure custom domain
  • [ ] Set up monitoring/analytics
  • [ ] Create backup strategy
  • [ ] Document deployment process

Troubleshooting

404 Errors

  1. Client-side routing: Configure server for SPA
  2. Base path: Check base config matches deployment path
  3. Case sensitivity: URLs are case-sensitive on Linux servers

Build Failures

bash
# Clear cache and rebuild
rm -rf node_modules/.rspress doc_build
npm install
npm run build

Slow Loading

  1. Enable compression (Gzip/Brotli)
  2. Use CDN for assets
  3. Optimize images
  4. Check bundle sizes
  5. Enable HTTP/2

Cache Issues

bash
# Bust cache by adding version query
# Or configure cache control headers properly

Best Practices

Performance

  • Enable CDN
  • Use HTTP/2
  • Enable compression
  • Optimize images
  • Set proper cache headers
  • Minimize JavaScript
  • Use lazy loading

Security

  • Enable HTTPS
  • Set security headers
  • Validate user input
  • Keep dependencies updated
  • Use Content Security Policy

Reliability

  • Automated deployments
  • Staging environment
  • Rollback capability
  • Health checks
  • Error monitoring
  • Backup strategy

Next Steps

Congratulations on completing the Rspress tutorial! You now have the knowledge to:

  • Create and structure documentation sites
  • Configure navigation and routing
  • Use MDX and React components
  • Handle static assets
  • Implement internationalization
  • Deploy to various platforms

Additional Resources


Quick Deploy

For fastest deployment:

  1. Vercel: vercel (GitHub integration)
  2. Netlify: Drag & drop doc_build folder
  3. GitHub Pages: Enable in repository settings

Production Checklist

  • ✅ HTTPS enabled
  • ✅ Custom domain configured
  • ✅ Analytics set up
  • ✅ Error monitoring active
  • ✅ Backups configured
  • ✅ CI/CD pipeline working

Content is for learning and research only.