A Vite plugin to generate static SEO pages from React components using ReactDOMServer.renderToString, without requiring complex SSR frameworks.
- ✅ Generate static HTML pages from React components
- ✅ Simple "use static" directive to mark SEO pages
- ✅ Automatic validation - prevents stateful React hooks
- ✅ CamelCase to snake-case route conversion
- ✅ Developer hooks for SEO metadata
- ✅ Works with existing Vite + React setup
- 🚧 Optional markdown support (coming soon)
npm install @deadsimpleseo/vite-deadsimpleseo @deadsimpleseo/deadsimpleseo-react
# or
yarn add @deadsimpleseo/vite-deadsimpleseo @deadsimpleseo/deadsimpleseo-react
# or
pnpm add @deadsimpleseo/vite-deadsimpleseo @deadsimpleseo/deadsimpleseo-reactAdd the plugin to your vite.config.ts:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import deadSimpleSEO from 'vite-deadsimpleseo';
export default defineConfig({
plugins: [
react(),
deadSimpleSEO({
pagesDir: 'src/seo-pages', // default
markdown: false, // default
}),
],
});Create components in src/seo-pages/ directory:
// src/seo-pages/AboutUs.tsx
"use static";
export default function AboutUs() {
return (
<div>
<h1>About Us</h1>
<p>Welcome to our company. We've been serving customers since 2020.</p>
</div>
);
}
export const seoMeta = {
title: 'About Us - Company Name',
description: 'Learn more about our company and mission',
};This will generate a static page at /about-us/index.html.
// Access SEO page metadata
import { useSEOPage, useSEOPages } from 'vite-deadsimpleseo/hooks';
function MyComponent() {
const { pageTitle, pageContent } = useSEOPage();
const allPages = useSEOPages(); // List of all SEO pages
return <div>{pageTitle}</div>;
}// Check if current route is an SEO page
import { isSEOPage } from 'vite-deadsimpleseo/utils';
// Can be used outside React context
if (!isSEOPage()) {
// Initialize React app normally
ReactDOM.createRoot(document.getElementById('root')!).render(<App />);
}interface DeadSimpleSEOConfig {
/**
* Directory containing SEO page components
* @default 'src/seo-pages'
*/
pagesDir?: string;
/**
* Output directory for static pages
* @default 'dist'
*/
outDir?: string;
/**
* Enable markdown support
* @default false
*/
markdown?: boolean;
/**
* Custom route transformation function
*/
routeTransform?: (name: string) => string;
/**
* SEO metadata defaults
*/
defaults?: {
title?: string;
description?: string;
ogImage?: string;
};
}- Discovery: Scans
pagesDirfor React components - Validation: Checks for "use static" directive and validates no stateful hooks
- Route Generation: Converts CamelCase names to snake-case routes
AboutUs.tsx→/about-us/index.htmlContactPage.tsx→/contact-page/index.html
- Static Generation: Renders components to static HTML during build
- SEO Optimization: Each page gets its own HTML file for better SEO
- Page components may include
"use static";directive at the top.
When present, the following React hook restrictions apply:
- ✅ useContext - works if provider is in parent component hierarchy
- ❌ useState, useEffect, useReducer, etc. - not allowed
- Note: While ReactDOMServer supports these hooks, 'use static' components are intentionally more restrictive to keep SEO pages simple and predictable
-
Layout-based hooks (such as useLayoutEffect and useEffect) are not supported.
-
SEO page components must be default exports
-
Component names should be PascalCase
-
Files starting with
_or namedindexare ignored
# Install dependencies
npm install
# Build the plugin
npm run build
# Watch mode for development
npm run devMIT
- Full ReactDOMServer.renderToString integration
- Markdown support with frontmatter
- Sitemap.xml generation
- Social media meta tags
- Image optimization
- Multi-language support