Configuration
Complete reference for ssr.config.js and environment variables.
ssr.config.js
The config file controls routing, SEO metadata, and build behavior.
// ssr.config.js
export default {
// === Site Identity ===
siteUrl: 'https://example.com', // Required. No trailing slash
siteName: 'Example', // Site name for OG tags
author: 'Your Name', // Author for meta tags
tagline: 'Your site tagline', // Short description
ogImage: 'https://example.com/og.png', // Default OG image
keywords: 'keyword1, keyword2', // Comma-separated
// === App Configuration ===
appLayoutPath: '/src/AppLayout.jsx', // Path to your AppLayout component
// === Routes ===
routes: [
{
path: '/', // Route path (required)
priority: '1.0', // Sitemap priority (0.0-1.0)
changefreq: 'weekly', // Sitemap change frequency
meta: { // Page-specific meta
title: 'Home | Example',
description: 'Homepage description',
}
}
],
// === Structured Data ===
buildJsonLd() {
// Return array of JSON-LD objects
return [
{
'@context': 'https://schema.org',
'@type': 'Organization',
name: 'Example',
url: 'https://example.com',
}
]
},
// === Optional: Proxy Configuration ===
proxy: {
url: 'https://proxy.example.com', // Proxy server URL
targetUrl: 'https://target.com', // Origin to render
secret: 'your-secret-token', // Auth secret
botList: ['googlebot', 'bingbot'], // User-agents to proxy
}
}
Route Configuration
Each route in the routes array supports:
{
path: '/about/', // Route path (required)
priority: '0.8', // Sitemap priority (string!)
changefreq: 'monthly', // Options: always, hourly, daily, weekly, monthly, never
meta: {
title: 'About | Example', // Page title
description: 'About page desc', // Meta description
ogImage: '/about-og.jpg', // Optional: override default ogImage
noindex: false, // Optional: add noindex meta
canonical: '/about/', // Optional: explicit canonical URL
}
}
Environment Variables
Build Time
| Variable | Description | Example |
|---|---|---|
VITE_SITE_URL |
Override site URL | https://staging.example.com |
NODE_ENV |
Node environment | production |
Runtime (Cloudflare Pages)
| Variable | Description | Example |
|---|---|---|
PRODUCTION |
Enable production mode | true |
PRESTRUCT_SECRET |
Proxy auth secret | (set in Cloudflare) |
PRESTRUCT_TARGET_URL |
Proxy target URL | https://origin.example.com |
File: public/_headers
Security and caching headers for Cloudflare Pages:
/*
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self' https://api.example.com
/*
Cache-Control: public, max-age=0, must-revalidate
/assets/*
Cache-Control: public, max-age=31536000, immutable
File: public/_redirects
Cloudflare Pages redirect rules:
/old-page/ /new-page/ 301
/legacy/* / 301
Complete Example
// ssr.config.js
export default {
siteUrl: 'https://mysite.com',
siteName: 'My Awesome Site',
author: 'Jane Doe',
tagline: 'Building awesome things',
ogImage: 'https://mysite.com/og-default.png',
keywords: 'react, cloudflare, static site',
appLayoutPath: '/src/AppLayout.jsx',
routes: [
{
path: '/',
priority: '1.0',
changefreq: 'daily',
meta: {
title: 'My Awesome Site',
description: 'Welcome to my awesome site!',
}
},
{
path: '/about/',
priority: '0.8',
changefreq: 'monthly',
meta: {
title: 'About | My Awesome Site',
description: 'Learn more about what we do',
}
},
{
path: '/blog/',
priority: '0.7',
changefreq: 'weekly',
meta: {
title: 'Blog | My Awesome Site',
description: 'Latest news and updates',
}
},
{
path: '/contact/',
priority: '0.6',
changefreq: 'monthly',
meta: {
title: 'Contact | My Awesome Site',
description: 'Get in touch with us',
}
}
],
buildJsonLd() {
return [
{
'@context': 'https://schema.org',
'@type': 'WebSite',
name: 'My Awesome Site',
url: 'https://mysite.com',
potentialAction: {
'@type': 'SearchAction',
target: 'https://mysite.com/search?q={search_term_string}',
'query-input': 'required name=search_term_string'
}
},
{
'@context': 'https://schema.org',
'@type': 'Organization',
name: 'My Awesome Site',
url: 'https://mysite.com',
logo: 'https://mysite.com/logo.png',
sameAs: [
'https://twitter.com/mysite',
'https://github.com/mysite'
]
}
]
}
}
TypeScript Support
If using TypeScript, create a ssr.config.ts:
import { defineConfig } from 'prestruct'
export default defineConfig({
siteUrl: 'https://example.com',
siteName: 'Example',
routes: [
{
path: '/',
priority: '1.0',
changefreq: 'weekly',
meta: {
title: 'Home | Example',
description: 'My site',
}
}
]
})