@capyseo/sveltekit
v0.1.2
Published
SvelteKit integration for Capyseo SEO analyzer - analyze pages during development and build
Maintainers
Readme
@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
- Quick Start
- Vite Plugin (Build-time)
- Server Hooks (Dev-time)
- AI-Powered Suggestions
- Configuration Options
- Examples
- Troubleshooting
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/coreQuick Start
Option 1: Vite Plugin (Recommended for CI/CD)
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.
Option 2: Server Hooks (Recommended for Development)
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:imageEnable 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:
- Install Ollama: https://ollama.ai
- Pull a model:
ollama pull llama3.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"
- Check the file is named
src/hooks.server.ts(notsrc/hooks.ts) - Make sure you're exporting
handle:export const handle = createCapyseoHandle();
"AI suggestions not appearing"
Verify your API key is set:
echo $OPENAI_API_KEYCheck 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:
- Fix the SEO issues (recommended)
- Lower the threshold:
capyseo({ minScore: 70 }) - Exclude problem pages:
capyseo({ exclude: ['/draft/*'] })
Related Packages
| Package | Description | |---------|-------------| | @capyseo/core | Core analysis engine (for custom integrations) | | @capyseo/cli | Command-line interface (for any site) |
Contributing
See CONTRIBUTING.md for development setup and guidelines.
Security
To report vulnerabilities, see SECURITY.md.
License
MIT © Capyseo
