Deployment Overview

Deploy your Specra documentation to production on any platform

Deployment Overview

Specra is built on SvelteKit, which means you can deploy it almost anywhere. This guide covers the most popular deployment options and how to configure Specra for each.

Deployment Targets

Specra supports two deployment modes:

Specra Cloud (Recommended)

  • One-command deploy with the Specra CLI
  • Automatic HTTPS with custom subdomains
  • Built-in analytics and feedback widgets
  • Managed infrastructure — no servers to configure

Static Export (Self-hosted)

  • GitHub Pages, Netlify, Cloudflare Pages
  • Pre-rendered HTML/CSS/JS
  • No server required
  • Great for open source docs

Quick Deployment

Deploy with two commands using the Specra CLI:

Authenticate

Log in with your Specra account. This opens a browser window for authentication:
Code
bash
1npx create-specra login
After signing in, the auth token is saved to your project's `.env` file as `SPECRA_TOKEN`. This keeps credentials local to each project.

To store the token globally (shared across all projects) instead, use the `--global` flag:
Code
bash
1npx create-specra login --global
This saves the token to `~/.specra/config.json`.
Info
Project-level `.env` tokens take priority over the global config. Add `.env` to your `.gitignore` to keep tokens out of version control.

Deploy

From your project directory, run:
Code
bash
1npx create-specra deploy
The CLI builds your project and deploys it to Specra Cloud. You'll get a live URL like `your-project.docs.specra-docs.com`.

Use `--verbose` to see full build output:
Code
bash
1npx create-specra deploy --verbose
Success
That's it! Your docs are live with automatic HTTPS, analytics, and a custom subdomain.

GitHub Pages

Perfect for open source documentation:

Configure for Static Export

Update `specra.config.json`:
Code
json
1{
2 "deployment": {
3 "target": "github-pages",
4 "basePath": "your-repo-name",
5 "customDomain": false
6 }
7}

Replace your-repo-name with your actual repository name.

Info
If using a custom domain (like `docs.yoursite.com`), set `customDomain: true` and leave `basePath` empty.

Build Static Site

Code
bash
1npm run build:export

This creates an out/ directory with your static site.

Deploy with GitHub Actions

Create `.github/workflows/deploy.yml`:
Code
yaml
1name: Deploy to GitHub Pages
2 
3on:
4 push:
5 branches: [main]
6 
7permissions:
8 contents: read
9 pages: write
10 id-token: write
11 
12jobs:
13 build:
14 runs-on: ubuntu-latest
15 steps:
16 - uses: actions/checkout@v4
17 
18 - name: Setup Node.js
19 uses: actions/setup-node@v4
20 with:
21 node-version: '20'
22 cache: 'npm'
23 
24 - name: Install dependencies
25 run: npm ci
26 
27 - name: Build site
28 run: npm run build:export
29 
30 - name: Upload artifact
31 uses: actions/upload-pages-artifact@v3
32 with:
33 path: ./out
34 
35 deploy:
36 needs: build
37 runs-on: ubuntu-latest
38 environment:
39 name: github-pages
40 url: ${{ steps.deployment.outputs.page_url }}
41 steps:
42 - name: Deploy to GitHub Pages
43 id: deployment
44 uses: actions/deploy-pages@v4

Enable GitHub Pages

  1. Go to your repo settings
  2. Navigate to Pages
  3. Source: GitHub Actions
  4. Save
Your docs will be live at `https://username.github.io/repo-name`

Netlify

Another great static hosting option:

Configure

Code
json
1{
2 "deployment": {
3 "target": "static"
4 }
5}

Create netlify.toml

Code
toml
1[build]
2 command = "npm run build:export"
3 publish = "out"

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

  </Step>

  <Step title="Deploy">
    Connect your repo at [netlify.com](https://netlify.com) or use the CLI:

```bash
npm install -g netlify-cli
netlify deploy --prod

Build Commands

Different platforms need different build commands:

PlatformBuild CommandOutput Directory
Specra Cloudnpx create-specra deploy (handles build)Managed
GitHub Pagesnpm run build:exportout
Netlify, Cloudflare Pagesnpm run build:exportout
Docker, VPSnpm run build + npm startbuild

Configuration by Platform

Specra Cloud

No config file needed. The CLI reads your specra.config.json automatically.

To customize the subdomain or project settings, use the Specra dashboard or pass options to the CLI:

Code
bash
1npx create-specra deploy --project my-docs

GitHub Pages (No Custom Domain)

Code
json
1{
2 "deployment": {
3 "target": "github-pages",
4 "basePath": "repo-name"
5 }
6}

Why basePath? GitHub Pages serves from username.github.io/repo-name, so all assets need the /repo-name prefix.

GitHub Pages (With Custom Domain)

Code
json
1{
2 "deployment": {
3 "target": "custom-domain-static",
4 "customDomain": true
5 }
6}

Add a CNAME file to public/:

docs.yoursite.com

Netlify / Cloudflare Pages

Code
json
1{
2 "deployment": {
3 "target": "static"
4 }
5}

No basePath needed - they serve from root.

CI/CD Pipelines

GitHub Actions (Advanced)

Full example with caching and MeiliSearch indexing:

Code
yaml
1name: Build and Deploy
2 
3on:
4 push:
5 branches: [main]
6 pull_request:
7 branches: [main]
8 
9jobs:
10 build:
11 runs-on: ubuntu-latest
12 
13 steps:
14 - uses: actions/checkout@v4
15 
16 - name: Setup Node.js
17 uses: actions/setup-node@v4
18 with:
19 node-version: '20'
20 cache: 'npm'
21 
22 - name: Cache dependencies
23 uses: actions/cache@v4
24 with:
25 path: ~/.npm
26 key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
27 restore-keys: |
28 ${{ runner.os }}-node-
29 
30 - name: Install dependencies
31 run: npm ci
32 
33 - name: Run linter
34 run: npm run lint
35 
36 - name: Build site
37 run: npm run build:export
38 env:
39 NODE_ENV: production
40 
41 - name: Index search content
42 if: github.ref == 'refs/heads/main'
43 run: npm run index:search
44 env:
45 MEILISEARCH_HOST: ${{ secrets.MEILISEARCH_HOST }}
46 MEILISEARCH_API_KEY: ${{ secrets.MEILISEARCH_MASTER_KEY }}
47 
48 - name: Upload artifact
49 uses: actions/upload-pages-artifact@v3
50 with:
51 path: ./out
52 
53 deploy:
54 if: github.ref == 'refs/heads/main'
55 needs: build
56 runs-on: ubuntu-latest
57 environment:
58 name: github-pages
59 url: ${{ steps.deployment.outputs.page_url }}
60 permissions:
61 pages: write
62 id-token: write
63 steps:
64 - name: Deploy to GitHub Pages
65 id: deployment
66 uses: actions/deploy-pages@v4

GitLab CI/CD

Code
yaml
1# .gitlab-ci.yml
2image: node:20
3 
4cache:
5 paths:
6 - node_modules/
7 
8stages:
9 - build
10 - deploy
11 
12build:
13 stage: build
14 script:
15 - npm ci
16 - npm run build:export
17 artifacts:
18 paths:
19 - out/
20 only:
21 - main
22 
23pages:
24 stage: deploy
25 dependencies:
26 - build
27 script:
28 - mkdir -p public
29 - cp -r out/* public/
30 artifacts:
31 paths:
32 - public
33 only:
34 - main

Docker

Create a Dockerfile:

Code
dockerfile
1FROM node:20-alpine AS builder
2 
3WORKDIR /app
4 
5COPY package*.json ./
6RUN npm ci
7 
8COPY . .
9RUN npm run build
10 
11FROM node:20-alpine AS runner
12 
13WORKDIR /app
14 
15ENV NODE_ENV=production
16 
17COPY --from=builder /app/public ./public
18COPY --from=builder /app/build ./
19COPY --from=builder /app/build/client ./build/client
20 
21EXPOSE 3000
22 
23CMD ["node", "server.js"]

Build and run:

Code
bash
1docker build -t my-docs .
2docker run -p 3000:3000 my-docs

Environment Variables

Set these in your deployment platform:

Search (if using MeiliSearch):

Code
bash
1MEILISEARCH_HOST=https://search.example.com
2MEILISEARCH_API_KEY=your-search-key

Analytics (optional):

Code
bash
1PUBLIC_GA_ID=G-XXXXXXXXXX
2PUBLIC_PLAUSIBLE_DOMAIN=docs.example.com

Custom env variables: Access them in your docs via frontmatter or MDX:

Code
json
1{
2 "env": {
3 "API_BASE_URL": "${API_URL}"
4 }
5}

Custom Domains

Specra Cloud

Custom subdomains are automatic. For a fully custom domain:

  1. Go to your project settings in the Specra dashboard
  2. Add your custom domain (e.g., docs.yoursite.com)
  3. Add a CNAME record pointing to docs.specra-docs.com
  4. Specra automatically provisions an SSL certificate

GitHub Pages

  1. Add CNAME file to public/:
docs.yoursite.com
  1. Update specra.config.json:
Code
json
1{
2 "deployment": {
3 "customDomain": true
4 }
5}
  1. Configure DNS:
Type: CNAME
Name: docs
Value: username.github.io

Netlify

  1. Go to Domain settings
  2. Add custom domain
  3. Follow DNS instructions

Performance Optimization

Enable Caching

Add cache headers in svelte.config.js:

Code
javascript
1async headers() {
2 return [
3 {
4 source: '/docs/:path*',
5 headers: [
6 {
7 key: 'Cache-Control',
8 value: 'public, max-age=3600, must-revalidate',
9 },
10 ],
11 },
12 ]
13}

Image Optimization

Use optimized images:

Code
mdx
1<Image
2 src="/images/diagram.png"
3 alt="Architecture diagram"
4 width={800}
5 height={600}
6/>

Bundle Analysis

Check bundle size:

Code
bash
1npm install --save-dev vite-bundle-visualizer

Run with:

Code
bash
1ANALYZE=true npm run build

Troubleshooting

404 on Page Refresh (Static Export)

Add redirects/rewrites in platform config:

Netlify:

Code
toml
1[[redirects]]
2 from = "/*"
3 to = "/index.html"
4 status = 200

Assets Not Loading (GitHub Pages)

Check your basePath matches your repo name exactly:

Code
json
1{
2 "deployment": {
3 "basePath": "exact-repo-name"
4 }
5}

Build Fails

Common fixes:

  1. Clear build artifacts:
Code
bash
1rm -rf .svelte-kit build node_modules
2npm install
3npm run build
  1. Check Node.js version:
Code
bash
1node --version # Should be 18+
  1. Review build logs for specific errors

Platform-Specific Guides

Dive deeper into platform-specific deployment:

Next Steps