capyseo-sveltekit Svelte Themes

Capyseo Sveltekit

SvelteKit integration for Capyseo with Vite plugin for build-time analysis and server hooks for real-time dev feedback.

@capyseo/sveltekit

SvelteKit integration for Capyseo with Vite plugin and dev-time server hooks.

Documentation Β· GitHub Β· Report Issue

Part of the Capyseo toolkit.


Overview

Deep SvelteKit integration for the Capyseo SEO analyzer. Get real-time SEO feedback during development and enforce SEO quality in your CI/CD pipeline.


Why Use This?

While you can use the CLI to analyze any built site, this package provides SvelteKit-specific integrations that make SEO analysis seamless:

  • πŸ”Œ Vite Plugin β€” Analyze your pages automatically when you build
  • πŸͺ Server Hooks β€” See SEO issues in real-time as you develop
  • 🎯 Framework-native β€” Works with SvelteKit's routing, prerendering, and adapters
  • ⚑ Zero config β€” Just add the plugin and start seeing results

Table of Contents


Installation

# Using npm
npm install @capyseo/sveltekit @capyseo/core

# Using Bun (recommended)
bun add @capyseo/sveltekit @capyseo/core

# Using pnpm
pnpm add @capyseo/sveltekit @capyseo/core

Quick Start

Add the Vite plugin to analyze pages during vite build:

// vite.config.ts
import { sveltekit } from '@sveltejs/kit/vite';
import { capyseo } from '@capyseo/sveltekit/vite';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [
    sveltekit(),
    capyseo(),
  ],
});

Now when you run vite build, you'll see SEO analysis for each page.

Add server hooks to see SEO issues in real-time as you browse your dev server:

// src/hooks.server.ts
import { createCapyseoHandle } from '@capyseo/sveltekit/hooks';

export const handle = createCapyseoHandle();

Now visit any page on http://localhost:5173 and check your terminal for SEO feedback.


Vite Plugin (Build-time)

The Vite plugin analyzes your pages during vite build. This is ideal for:

  • CI/CD pipelines (fail builds on low SEO scores)
  • Pre-deployment checks
  • Generating SEO reports

Basic Setup

// vite.config.ts
import { sveltekit } from '@sveltejs/kit/vite';
import { capyseo } from '@capyseo/sveltekit/vite';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [
    sveltekit(),
    capyseo({
      // Options here
    }),
  ],
});

Fail Builds on Low Scores

Perfect for CI/CDβ€”prevent deploying sites with SEO issues:

capyseo({
  // Fail build if any page scores below 80
  minScore: 80,

  // Fail build if there are any SEO errors
  failOnError: true,
})

Exclude Paths

Skip pages that don't need SEO analysis:

capyseo({
  exclude: [
    '/admin/*',      // Admin pages
    '/api/*',        // API routes
    '/preview/*',    // Preview pages
    '/__data.json',  // SvelteKit data endpoints
  ],
})

Enable AI Suggestions

Get AI-generated meta descriptions and alt text:

capyseo({
  // Using environment variable
  geminiApiKey: process.env.GEMINI_API_KEY,

  // Or specify the provider
  aiProvider: 'openai',
  aiApiKey: process.env.OPENAI_API_KEY,
})

Custom Report Handler

Process analysis results programmatically:

capyseo({
  onReport: (reports) => {
    // Calculate average score
    const avg = reports.reduce((sum, r) => sum + r.score, 0) / reports.length;
    console.log(`Average SEO score: ${avg.toFixed(1)}/100`);

    // Find worst pages
    const worst = reports.filter(r => r.score < 70);
    if (worst.length > 0) {
      console.log('Pages needing attention:', worst.map(r => r.url));
    }

    // Write custom report
    fs.writeFileSync('seo-summary.json', JSON.stringify({
      averageScore: avg,
      totalPages: reports.length,
      issueCount: reports.reduce((sum, r) => sum + r.issues.length, 0),
    }));
  },
})

Full Plugin Options

interface VitePluginOptions {
  // Enable/disable analysis (defaults to true in dev)
  analyze?: boolean;

  // Minimum score to pass build (0-100)
  minScore?: number;

  // Fail build on any SEO errors
  failOnError?: boolean;

  // Paths to exclude from analysis (glob patterns)
  exclude?: string[];

  // AI provider: 'openai' | 'anthropic' | 'gemini' | 'ollama'
  aiProvider?: string;

  // API key for AI provider
  aiApiKey?: string;
  geminiApiKey?: string;  // Shorthand for Gemini

  // Ollama base URL (default: http://localhost:11434)
  ollamaBaseUrl?: string;

  // Custom report handler
  onReport?: (reports: Report[]) => void;
}

Server Hooks (Dev-time)

Server hooks analyze pages in real-time as you develop. This is ideal for:

  • Immediate feedback while coding
  • Catching SEO issues before committing
  • Learning SEO best practices

Basic Setup

// src/hooks.server.ts
import { createCapyseoHandle } from '@capyseo/sveltekit/hooks';

export const handle = createCapyseoHandle();

Combine with Other Hooks

Using SvelteKit's sequence helper:

// src/hooks.server.ts
import { sequence } from '@sveltejs/kit/hooks';
import { createCapyseoHandle } from '@capyseo/sveltekit/hooks';

const capyseoHandle = createCapyseoHandle({
  logLevel: 'issues',
});

const authHandle = async ({ event, resolve }) => {
  // Your auth logic
  return resolve(event);
};

export const handle = sequence(capyseoHandle, authHandle);

Log Level Options

Control how much output you see:

createCapyseoHandle({
  // 'none' β€” No output
  // 'issues' β€” Only pages with SEO issues (default)
  // 'all' β€” Every page analyzed
  logLevel: 'issues',
})

Example output with logLevel: 'issues':

[capyseo] /about (Score: 72/100)
  βœ— [meta-description] Missing meta description
  ! [open-graph] Missing og:image

Enable Only in Development

createCapyseoHandle({
  enabled: process.env.NODE_ENV === 'development',
})

Custom Report Handler

Process results programmatically:

createCapyseoHandle({
  onReport: (report) => {
    // Send to monitoring service
    if (report.score < 70) {
      console.warn(`⚠️ Low SEO score on ${report.url}: ${report.score}/100`);
    }

    // Track specific issues
    const missingMeta = report.issues.filter(i =>
      i.rule === 'meta-description' || i.rule === 'meta-title'
    );
    if (missingMeta.length > 0) {
      console.warn('Missing meta tags:', missingMeta);
    }
  },
})

Full Hooks Options

interface HooksOptions {
  // Enable/disable analysis (defaults to true in dev)
  enabled?: boolean;

  // Log level: 'none' | 'issues' | 'all'
  logLevel?: 'none' | 'issues' | 'all';

  // Paths to exclude from analysis (glob patterns)
  exclude?: string[];

  // AI provider settings
  aiProvider?: string;
  aiApiKey?: string;

  // Custom report handler (called for each page)
  onReport?: (report: Report) => void;
}

AI-Powered Suggestions

Both the Vite plugin and server hooks support AI-powered suggestions. When enabled, Capyseo will:

  • Generate meta descriptions β€” Based on your page content
  • Suggest alt text β€” For images missing descriptions
  • Recommend improvements β€” Title tweaks, keyword suggestions

Using OpenAI

// vite.config.ts
capyseo({
  aiProvider: 'openai',
  aiApiKey: process.env.OPENAI_API_KEY,
})

Using Anthropic (Claude)

capyseo({
  aiProvider: 'anthropic',
  aiApiKey: process.env.ANTHROPIC_API_KEY,
})

Using Google Gemini

capyseo({
  aiProvider: 'gemini',
  aiApiKey: process.env.GEMINI_API_KEY,
  // Or use the shorthand:
  geminiApiKey: process.env.GEMINI_API_KEY,
})

Using Ollama (Free, Local)

Run AI locally without API keys:

  1. Install Ollama: https://ollama.ai
  2. Pull a model: ollama pull llama3.3
  3. Configure:
capyseo({
  aiProvider: 'ollama',
  // Optional: custom URL if not running locally
  ollamaBaseUrl: 'http://localhost:11434',
})

Recommended models by hardware:

Hardware Model Command
RTX 4090 (24GB) ollama pull deepseek-r1:70b
RTX 4070 (12GB) ollama pull qwen3-coder:14b
M4 Pro (48GB) ollama pull deepseek-r1:70b
M4 (16GB) ollama pull qwen3-coder:14b
CPU only ollama pull phi-3:3.8b

Configuration Options

Environment Variables

The plugins automatically read these environment variables:

Variable Description
OPENAI_API_KEY OpenAI API key
ANTHROPIC_API_KEY Anthropic API key
GEMINI_API_KEY Google Gemini API key
OLLAMA_BASE_URL Ollama server URL (default: http://localhost:11434)

SvelteKit Configuration

For best results, ensure your SvelteKit config outputs prerendered HTML:

// svelte.config.js
import adapter from '@sveltejs/adapter-static';

export default {
  kit: {
    adapter: adapter({
      fallback: 'index.html',
    }),
    prerender: {
      entries: ['*'],  // Prerender all pages
    },
  },
};

Examples

Minimal Setup (Dev + Build)

// vite.config.ts
import { sveltekit } from '@sveltejs/kit/vite';
import { capyseo } from '@capyseo/sveltekit/vite';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [sveltekit(), capyseo()],
});
// src/hooks.server.ts
import { createCapyseoHandle } from '@capyseo/sveltekit/hooks';
export const handle = createCapyseoHandle();

CI/CD with GitHub Actions

# .github/workflows/seo.yml
name: SEO Check

on: [push, pull_request]

jobs:
  seo:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: oven-sh/setup-bun@v2

      - run: bun install
      - run: bun run build
        env:
          # Build will fail if score < 80
          # (configured in vite.config.ts with minScore: 80)

Production Setup with AI

// vite.config.ts
import { sveltekit } from '@sveltejs/kit/vite';
import { capyseo } from '@capyseo/sveltekit/vite';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [
    sveltekit(),
    capyseo({
      // Strict requirements for production
      minScore: 85,
      failOnError: true,

      // Exclude non-public routes
      exclude: ['/admin/*', '/api/*', '/__*'],

      // AI suggestions in CI
      aiProvider: 'gemini',
      aiApiKey: process.env.GEMINI_API_KEY,

      // Custom reporting
      onReport: (reports) => {
        // Write report for deployment review
        const summary = {
          date: new Date().toISOString(),
          averageScore: reports.reduce((s, r) => s + r.score, 0) / reports.length,
          pageCount: reports.length,
          errorCount: reports.flatMap(r => r.issues).filter(i => i.severity === 'error').length,
        };
        fs.writeFileSync('seo-report.json', JSON.stringify(summary, null, 2));
      },
    }),
  ],
});

Troubleshooting

"No pages analyzed"

Make sure you're building with prerendering enabled:

// svelte.config.js
export default {
  kit: {
    prerender: {
      entries: ['*'],
    },
  },
};

"Hooks not running"

  1. Check the file is named src/hooks.server.ts (not src/hooks.ts)
  2. Make sure you're exporting handle:
    export const handle = createCapyseoHandle();
    

"AI suggestions not appearing"

  1. Verify your API key is set:

    echo $OPENAI_API_KEY
    
  2. Check you specified the provider:

    capyseo({
      aiProvider: 'openai',
      aiApiKey: process.env.OPENAI_API_KEY,
    })
    

"Build failing with low score"

If minScore is set and pages don't meet it, the build will fail. Either:

  1. Fix the SEO issues (recommended)
  2. Lower the threshold:
    capyseo({ minScore: 70 })
    
  3. Exclude problem pages:
    capyseo({ exclude: ['/draft/*'] })
    

Package Description
@capyseo/core Core analysis engine (for custom integrations)
@capyseo/cli Command-line interface (for any site)

Support


Contributing

See CONTRIBUTING.md for development setup and guidelines.


Security

To report vulnerabilities, see SECURITY.md.


License

MIT Β© Capyseo

Top categories

Loading Svelte Themes