ZepshSSG is a powerful static site generator that crawls modern web applications (ZepshJS, React, Vue, Svelte) and generates static HTML files for improved performance and SEO. It supports dynamic routes, sitemap generation, incremental builds, and provides a sleek CLI experience with interactive configuration.
This is a built-in tool for the ZepshJS web framework.
Static site generation transforms your dynamic single-page applications into pre-rendered HTML files, providing numerous benefits:
/users/:id
, /blog/:slug
)sitemap.xml
for enhanced SEOnpm install -g zepsh-ssg
npm install zepsh-ssg --save-dev
npx zepsh-ssg
# Using Yarn
yarn global add zepsh-ssg
# or locally
yarn add -D zepsh-ssg
# Using pnpm
pnpm add -g zepsh-ssg
# or locally
pnpm add -D zepsh-ssg
npx zepsh-ssg
# Build your React/Vue/Svelte app
npm run build
# Generate static site
npx zepsh-ssg --routes /,/about,/contact --sitemap --base-url https://mysite.com
# Deploy (example with Netlify)
netlify deploy --prod --dir=build-ssg
ZepshSSG offers flexible configuration with the following precedence order:
zepsh.config.js
or package.json
)Basic Usage:
npx zepsh-ssg --routes /,/about --port 5000 --out-dir static
Advanced Usage with Hydration:
npx zepsh-ssg --hydrate --hydrate-bundle assets/js/main.js --sitemap --base-url https://example.com
Complete Flag Reference:
Flag | Description | Corresponding Field |
---|---|---|
--routes <routes> |
Comma-separated routes or 'auto' for auto-detection | routes |
--base-path <path> |
Base path prefix for all routes | basePath |
--base-url <url> |
Base URL for sitemap generation (e.g., https://example.com ) |
baseUrl |
-i, --input-dir <path> |
Input directory containing built files | inputDir |
-o, --out-dir <path> |
Output directory for generated static files | outDir |
-p, --port <number> |
Development server port (1-65535) | port |
--concurrency <number> |
Number of concurrent crawling processes | concurrency |
--flat-output |
Generate page.html instead of page/index.html |
flatOutput |
--hydrate |
Enable client-side hydration (experimental) | hydrate |
--hydrate-bundle <path> |
Path to hydration bundle (relative to input directory) | hydrateBundle |
--framework <name> |
Target framework: react , vite , vue , or svelte |
framework |
--batch-size <number> |
Number of routes to process per batch | batchSize |
--incremental |
Enable incremental builds with caching (experimental) | incremental |
-t, --timeout <number> |
Timeout per route in milliseconds | timeout |
--inline-css |
Enable CSS inlining optimization | inlineCss |
--sitemap |
Generate sitemap.xml (recommended for SEO) | sitemap |
--exclude-routes <routes> |
Comma-separated routes to exclude from generation | excludeRoutes |
--custom-selectors <selectors> |
Custom CSS selectors for content extraction | customSelectors |
--watch |
Watch for file changes and rebuild automatically | - |
--dry-run |
Preview routes without generating files | - |
-V, --version |
Display version information | - |
-h, --help |
Show help information | - |
--clear-cache |
Clear cached data in .zepsh |
- |
--clear-logs |
Clear logs in .zepsh |
- |
--clean |
Clear all cache and logs in .zepsh |
- |
š” Tip: When using
--sitemap
, always specify--base-url
for proper SEO. Without it, URLs will default tohttps://localhost:3000
.
zepsh.config.js
(Recommended)export default {
ssg: {
routes: ["/", "/about", "/contact"],
inputDir: "dist",
outDir: "dist-ssg",
baseUrl: "https://mysite.com",
sitemap: true,
framework: "react",
concurrency: 5,
timeout: 45000,
hydrate: true,
hydrateBundle: "assets/js/bundle.js",
},
};
package.json
{
"name": "my-app",
"scripts": {
"build": "vite build",
"ssg": "zepsh-ssg"
},
"zepsh": {
"ssg": {
"routes": ["/", "/about", "/contact"],
"inputDir": "dist",
"outDir": "dist-ssg",
"baseUrl": "https://mysite.com",
"sitemap": true
}
}
}
For applications with dynamic routes, use objects with path
and params
:
export default {
ssg: {
routes: [
"/",
"/about",
{
path: "/users/:id",
params: [{ id: "1" }, { id: "2" }, { id: "admin" }],
},
{
path: "/blog/:category/:slug",
params: [
{ category: "tech", slug: "react-tips" },
{ category: "design", slug: "ui-patterns" },
],
},
],
// ... other configuration
},
};
Field | Type | Description | Default | CLI Flag |
---|---|---|---|---|
routes |
string[] | object[] |
Routes to crawl or 'auto' for detection | ['/'] |
--routes |
basePath |
string |
Base path prefix for routes | '' |
--base-path |
baseUrl |
string |
Base URL for sitemap and canonical URLs | 'http://localhost:3000' |
--base-url |
inputDir |
string |
Directory containing built application files | 'build' |
-i, --input-dir |
outDir |
string |
Output directory for static files | 'build-ssg' |
-o, --out-dir |
port |
number |
Development server port | 3000 |
-p, --port |
concurrency |
number |
Concurrent crawling processes | 3 |
--concurrency |
flatOutput |
boolean |
Flat file structure vs. directory structure | false |
--flat-output |
hydrate |
boolean |
Enable client-side hydration (experimental) | false |
--hydrate |
hydrateBundle |
string |
Path to hydration JavaScript bundle | null |
--hydrate-bundle |
framework |
'react' | 'vite' | 'vue' | 'svelte' |
Target framework for optimization | 'react' |
--framework |
batchSize |
number |
Routes processed per batch | 50 |
--batch-size |
incremental |
boolean |
Enable incremental builds (experimental) | false |
--incremental |
timeout |
number |
Timeout per route in milliseconds | 30000 |
-t, --timeout |
inlineCss |
boolean |
Enable CSS inlining with Critters | false |
--inline-css |
sitemap |
boolean |
Generate sitemap.xml | false |
--sitemap |
excludeRoutes |
string[] |
Routes to exclude from generation | [] |
--exclude-routes |
customSelectors |
string[] |
Custom CSS selectors for content | [] |
--custom-selectors |
ā ļø Note: CLI flags always override configuration file settings. Features like
--watch
and--dry-run
are CLI-only but can be combined with file configuration.
When no configuration is detected, ZepshSSG launches an interactive setup wizard:
npx zepsh-ssg
? Input directory (where your built files are located): dist
? Output directory (where static files will be saved): dist-ssg
? Server port (1-65535): 3000
? Routes to crawl (comma-separated or 'auto'): /,/about,/users/:id[1,2,3]
? Enable sitemap generation? (Y/n): Y
? Base URL for sitemap: https://mysite.com
? Framework (react/vite/vue/svelte): react
? Enable CSS inlining? (Y/n): Y
? Concurrency level (1-10): 3
The wizard saves your preferences and generates a configuration file for future use.
ZepshSSG automatically generates SEO-optimized sitemaps with proper lastmod timestamps and canonical URLs.
Enable sitemap generation:
npx zepsh-ssg --sitemap --base-url https://mysite.com
Generated sitemap.xml
example:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://mysite.com/</loc>
<lastmod>2025-05-30T04:42:18.000Z</lastmod>
<priority>1.0</priority>
</url>
<url>
<loc>https://mysite.com/about</loc>
<lastmod>2025-05-30T04:42:18.000Z</lastmod>
<priority>0.8</priority>
</url>
<url>
<loc>https://mysite.com/users/1</loc>
<lastmod>2025-05-30T04:42:18.000Z</lastmod>
<priority>0.6</priority>
</url>
</urlset>
Dramatically reduce build times by only regenerating changed routes. ZepshSSG maintains a cache of file hashes to detect changes.
Enable incremental builds:
npx zepsh-ssg --incremental
How it works:
.zepsh/caches/ssg.json
ā ļø Experimental: This feature is under active development. Please report issues on our GitHub repository.
ZepshSSG provides comprehensive debugging capabilities for troubleshooting generation issues.
Debug folder structure:
.zepsh/
āāā caches/
ā āāā ssg.json # Incremental build cache
āāā debug/
āāā logs/
ā āāā ssg.log # Detailed operation logs
āāā screenshots/
āāā ssg/
āāā _.png # Homepage screenshot
āāā _about.png # About page screenshot
āāā _users_1.png # Dynamic route screenshot
Add to .gitignore
:
# Dependencies
/node_modules/
# ZepshSSG debug and cache files
/.zepsh/
# Environment files
.env*
Automatically rebuild when source files change during development:
npx zepsh-ssg --watch
Perfect for development workflows where you want to see static generation results in real-time.
Add client-side interactivity to your static pages:
npx zepsh-ssg --hydrate --hydrate-bundle assets/js/app.js
How hydration works:
# Build React app
npm run build
# Generate static site
npx zepsh-ssg --framework react --input-dir build
# Build React app
npm run build
# Generate static site
npx zepsh-ssg --framework vite --input-dir dist --sitemap --base-url https://myapp.com
# Build Vue app
npm run generate
# Generate static site
npx zepsh-ssg --framework vue --input-dir .output/public --routes auto
# Build Svelte app
npm run build
# Generate static site
npx zepsh-ssg --framework svelte --input-dir build --hydrate
ZepshSSG uses Critters to inline critical CSS:
Configure batch processing for optimal performance:
# Process 20 routes at a time with 5 concurrent workers
npx zepsh-ssg --batch-size 20 --concurrency 5
For large sites, tune memory usage:
# Increase Node.js memory limit
NODE_OPTIONS="--max-old-space-size=4096" npx zepsh-ssg
ZepshSSG provides detailed logging and comprehensive reports:
āāāāāāāāāāāāāāāāāāāāāāā āāāāāāāāāāā āāā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā āāā
āāāāā āāāāāā āāāāāāāāāāāāāāāāāāāāāāāā
āāāāā āāāāāā āāāāāāā āāāāāāāāāāāāāāāā
āāāāāāāāāāāāāāāāāāā āāāāāāāāāāā āāā
āāāāāāāāāāāāāāāāāāā āāāāāāāāāāā āāā
v1.0.17
⢠Configuration
Routes : 15 routes (3 dynamic)
Input : dist
Output : dist-ssg
Port : 3000
Framework : react
Started : 5/30/2025, 7:05:18 PM
+ [7:05:18 PM] INFO Serving dist at http://localhost:3000
ā [7:05:19 PM] SUCCESS Copied 'dist' ā 'dist-ssg' (2.3 MB)
+ [7:05:20 PM] INFO Processing batch 1/3 (5 routes)...
+ [7:05:24 PM] SUCCESS CSS inlined for 5 routes
ā [7:05:24 PM] SUCCESS Batch 1/3 completed
+ [7:05:25 PM] INFO Processing batch 2/3 (5 routes)...
ā [7:05:28 PM] SUCCESS Batch 2/3 completed
+ [7:05:29 PM] INFO Processing batch 3/3 (5 routes)...
ā [7:05:32 PM] SUCCESS Batch 3/3 completed
+ [7:05:32 PM] INFO Cache saved: '.zepsh/caches/ssg.json'
+ [7:05:32 PM] SUCCESS Generated sitemap: 'dist-ssg/sitemap.xml'
ā [7:05:32 PM] SUCCESS Crawling finished
⢠Reports
Successful : 15 routes
Failed : 0 routes
Total : 15 routes
Skipped : 2 routes (excluded)
⢠Performance
Duration : 14.2s
Average : 0.95s per route
Cache hits : 3 routes
File size : 4.7 MB generated
+ [7:05:32 PM] SUCCESS All 15 route(s) processed successfully
+ [7:05:32 PM] SUCCESS Done!
1. Routes not found
# Enable debug mode and check auto-detection
npx zepsh-ssg --routes auto --dry-run
2. Build fails with timeout
# Increase timeout for complex pages
npx zepsh-ssg --timeout 60000
3. Memory issues
# Reduce concurrency and batch size
npx zepsh-ssg --concurrency 1 --batch-size 10
4. CSS not loading
# Enable CSS inlining if needed
npx zepsh-ssg --inline-css
Check debug logs for detailed information:
# View debug logs
cat .zepsh/debug/logs/ssg.log
# View generated screenshots
ls .zepsh/debug/screenshots/ssg/
name: Deploy Static Site
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: "18"
- name: Install dependencies
run: npm ci
- name: Build application
run: npm run build
- name: Generate static site
run: npx zepsh-ssg --sitemap --base-url https://mysite.com
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./build-ssg
Create netlify.toml
:
[build]
command = "npm run build && npx zepsh-ssg --sitemap --base-url https://mysite.netlify.app"
publish = "build-ssg"
[build.environment]
NODE_VERSION = "18"
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "DENY"
X-XSS-Protection = "1; mode=block"
Create vercel.json
:
{
"buildCommand": "npm run build && npx zepsh-ssg --sitemap --base-url https://mysite.vercel.app",
"outputDirectory": "build-ssg",
"framework": null
}
# Replace gatsby build with:
npm run build # Your normal build command
npx zepsh-ssg --routes auto --sitemap --base-url https://yoursite.com
# Replace next export with:
npm run build
npx zepsh-ssg --framework react --routes auto --sitemap
# Replace nuxt generate with:
npm run build
npx zepsh-ssg --framework vue --input-dir .output/public --routes auto
We welcome contributions! Here's how to get started:
git clone https://github.com/yourusername/zepsh-ssg.git
npm install
git checkout -b feature/amazing-feature
npm test
git commit -m 'Add amazing feature'
git push origin feature/amazing-feature
# Clone the repository
git clone https://github.com/zepsh/zepsh-ssg.git
cd zepsh-ssg
# Install dependencies
npm install
# Run tests
npm test
# Run in development mode
npm run dev
We use ESLint and Prettier for code formatting. Before submitting:
npm run lint # Check code style
npm run lint:fix # Auto-fix issues
npm run format # Format code
Please read our Contributing Guidelines for detailed information about our development process, issue reporting, and pull request procedures.
Apache-2.0 License - see LICENSE file for details.
ā Star us on GitHub if you find ZepshSSG helpful!