Documentation Index
Fetch the complete documentation index at: https://mintlify.com/cloudflare/vinext/llms.txt
Use this file to discover all available pages before exploring further.
Configuration Guide
vinext automatically loads your Next.js configuration and translates it to Vite. This guide covers both Next.js config options and Vite customization.
Next.js Configuration
vinext loads and respects your existing next.config.js:
// next.config.js
module.exports = {
reactStrictMode: true,
basePath: '/docs',
trailingSlash: true,
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'cdn.example.com',
},
],
},
};
vinext auto-detects configuration file formats:
next.config.js (CommonJS)
next.config.mjs (ES modules)
next.config.ts (TypeScript)
next.config.cjs (CommonJS with .cjs extension)
Supported Config Options
basePath
Add a path prefix to your application:
module.exports = {
basePath: '/docs',
};
All routes, links, and assets are automatically prefixed:
/ → /docs/
/about → /docs/about
<Link href="/blog"> → /docs/blog
trailingSlash
Control URL trailing slashes:
module.exports = {
trailingSlash: true, // /about/ instead of /about
};
vinext automatically redirects to the canonical form (308 Permanent Redirect).
env
Add custom environment variables:
module.exports = {
env: {
CUSTOM_KEY: 'my-value',
},
};
Access via process.env.CUSTOM_KEY in both server and client code.
NEXT_PUBLIC_* variables are always available on the client. Other variables are server-only unless explicitly added to env.
output
Control build output format:
module.exports = {
output: 'export', // Static site generation
};
Options:
'export' - Full static export (no server required)
'standalone' - Self-contained server (Node.js deployment)
undefined - Default (SSR + static optimization)
See Static Export Guide for details.
images
Configure image optimization:
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'cdn.example.com',
port: '',
pathname: '/images/**',
},
],
domains: ['legacy.example.com'], // Legacy API
unoptimized: false, // Set true to disable optimization
},
};
vinext performs runtime image optimization, not build-time. The config controls allowed origins but doesn’t affect build output.
redirects
URL redirects with pattern matching:
module.exports = {
async redirects() {
return [
{
source: '/old-blog/:slug',
destination: '/blog/:slug',
permanent: true, // 308 redirect
},
{
source: '/docs',
destination: '/docs/introduction',
permanent: false, // 307 redirect
},
];
},
};
Features:
- Path parameters (
:param)
- Wildcards (
:path* for catch-all)
- Conditional redirects with
has/missing
rewrites
Rewrite URLs without changing the browser address:
module.exports = {
async rewrites() {
return [
{
source: '/api/:path*',
destination: 'https://api.example.com/:path*',
},
];
},
};
Three phases:
module.exports = {
async rewrites() {
return {
beforeFiles: [
// Checked before pages/app/ files
{ source: '/some-page', destination: '/somewhere-else' },
],
afterFiles: [
// Checked after pages/app/ files
{ source: '/fallback/:path*', destination: '/api/:path*' },
],
fallback: [
// Checked after static files (public/)
{ source: '/:path*', destination: '/404' },
],
};
},
};
Add custom HTTP headers:
module.exports = {
async headers() {
return [
{
source: '/api/:path*',
headers: [
{ key: 'Access-Control-Allow-Origin', value: '*' },
{ key: 'Access-Control-Allow-Methods', value: 'GET,POST' },
],
},
];
},
};
i18n
Internationalization routing (Pages Router only):
module.exports = {
i18n: {
locales: ['en', 'fr', 'de'],
defaultLocale: 'en',
localeDetection: true, // Auto-detect from Accept-Language
},
};
vinext automatically:
- Prefixes URLs with locale (
/fr/about, /de/contact)
- Detects locale from
Accept-Language header
- Stores preference in
NEXT_LOCALE cookie
App Router uses a different i18n approach. See Next.js i18n docs for App Router patterns.
cacheComponents
Enable the “use cache” directive (Next.js 16+):
module.exports = {
cacheComponents: true,
};
Allows function and page-level caching:
'use cache';
export async function getCachedData() {
const data = await fetch('https://api.example.com/data');
return data.json();
}
Configs can be functions (useful for per-environment settings):
module.exports = (phase, { defaultConfig }) => {
if (phase === 'phase-development-server') {
return {
/* development config */
};
}
return {
/* production config */
};
};
Available phases:
phase-development-server - vinext dev
phase-production-build - vinext build
phase-production-server - vinext start
Vite Configuration
For advanced customization, create a vite.config.ts:
import { defineConfig } from 'vite';
import vinext from 'vinext';
export default defineConfig({
plugins: [vinext()],
});
Auto-Generated Config
Running vinext init or vinext deploy auto-generates a minimal vite.config.ts.
App Router:
import { defineConfig } from "vite";
import vinext from "vinext";
import { cloudflare } from "@cloudflare/vite-plugin";
export default defineConfig({
plugins: [
vinext(),
cloudflare({
viteEnvironment: {
name: "rsc",
childEnvironments: ["ssr"],
},
}),
],
});
Pages Router:
import { defineConfig } from "vite";
import vinext from "vinext";
import { cloudflare } from "@cloudflare/vite-plugin";
export default defineConfig({
plugins: [vinext(), cloudflare()],
});
TypeScript Path Aliases
vinext automatically resolves TypeScript path aliases from tsconfig.json:
// tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
"@/components/*": ["./src/components/*"],
"@/lib/*": ["./src/lib/*"]
}
}
}
No Vite configuration needed—imports work automatically:
import { Button } from '@/components/ui/button';
import { fetchData } from '@/lib/api';
This is handled by vite-tsconfig-paths, which vinext injects automatically.
MDX Support
vinext auto-detects MDX usage and configures @mdx-js/rollup with plugins from your Next.js config:
// next.config.js
const withMDX = require('@next/mdx')({
options: {
remarkPlugins: [remarkGfm],
rehypePlugins: [rehypeHighlight],
},
});
module.exports = withMDX({
pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'md', 'mdx'],
});
vinext extracts the remark/rehype plugins and applies them to @mdx-js/rollup automatically.
For manual MDX configuration:
import { defineConfig } from 'vite';
import vinext from 'vinext';
import mdx from '@mdx-js/rollup';
import remarkGfm from 'remark-gfm';
export default defineConfig({
plugins: [
vinext(),
mdx({
remarkPlugins: [remarkGfm],
}),
],
});
CSS and Styling
vinext supports all Vite CSS features out of the box:
Tailwind CSS
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
// tailwind.config.js
module.exports = {
content: [
'./app/**/*.{js,ts,jsx,tsx}',
'./pages/**/*.{js,ts,jsx,tsx}',
'./components/**/*.{js,ts,jsx,tsx}',
],
};
Import in your root layout:
/* app/globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
// app/layout.tsx
import './globals.css';
CSS Modules
/* Button.module.css */
.button {
background: blue;
color: white;
}
import styles from './Button.module.css';
export function Button() {
return <button className={styles.button}>Click me</button>;
}
PostCSS
Create postcss.config.cjs (note the .cjs extension for ESM projects):
module.exports = {
plugins: {
'tailwindcss': {},
'autoprefixer': {},
},
};
Build Options
export default defineConfig({
plugins: [vinext()],
build: {
target: 'esnext',
minify: 'esbuild',
sourcemap: true,
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom'],
},
},
},
},
});
Dev Server Options
export default defineConfig({
plugins: [vinext()],
server: {
port: 3000,
host: '0.0.0.0', // Bind to all interfaces
open: true, // Open browser on start
cors: true,
},
});
Optimization
export default defineConfig({
plugins: [vinext()],
optimizeDeps: {
include: ['large-library'], // Force pre-bundle
exclude: ['local-package'], // Don't pre-bundle
},
});
Aliasing Modules
For native modules that can’t run in Workers:
import path from 'node:path';
export default defineConfig({
plugins: [vinext()],
resolve: {
alias: {
'sharp': path.resolve(__dirname, 'empty-stub.js'),
'@resvg/resvg-js': path.resolve(__dirname, 'empty-stub.js'),
},
},
});
// empty-stub.js
export default {};
vinext automatically stubs common native modules (sharp, resvg, satori, lightningcss, @napi-rs/canvas) during vinext deploy.
Environment-Specific Config
import { defineConfig } from 'vite';
import vinext from 'vinext';
export default defineConfig(({ mode }) => {
const isDev = mode === 'development';
const isProd = mode === 'production';
return {
plugins: [vinext()],
build: {
minify: isProd,
sourcemap: isDev,
},
server: {
port: isDev ? 3000 : 8080,
},
};
});
Environment Variables
Development (.env.local)
# .env.local (not committed)
NEXT_PUBLIC_API_URL=http://localhost:3001/api
DATABASE_URL=postgresql://localhost/mydb
SECRET_KEY=dev-secret
Production (.env.production)
# .env.production (committed)
NEXT_PUBLIC_API_URL=https://api.example.com
Loading Priority
.env.local (highest priority, not committed)
.env.production or .env.development (environment-specific)
.env (shared defaults)
Runtime Access
// Server-side
const dbUrl = process.env.DATABASE_URL;
// Client-side (requires NEXT_PUBLIC_ prefix)
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
vinext Plugin Options
The vinext plugin accepts configuration:
import { defineConfig } from 'vite';
import vinext from 'vinext';
export default defineConfig({
plugins: [
vinext({
// Options coming in future versions
}),
],
});
Currently, vinext auto-configures based on your Next.js setup and doesn’t require explicit options. Future versions may add customization points.
Migration from Next.js Config
Webpack Config
Next.js:
module.exports = {
webpack: (config) => {
config.module.rules.push({
test: /\.svg$/,
use: ['@svgr/webpack'],
});
return config;
},
};
vinext: Use Vite plugins instead:
import { defineConfig } from 'vite';
import vinext from 'vinext';
import svgr from 'vite-plugin-svgr';
export default defineConfig({
plugins: [vinext(), svgr()],
});
Experimental Options
Most Next.js experimental options are not needed in vinext:
Next.js:
module.exports = {
experimental: {
appDir: true, // App Router
serverActions: true,
},
};
vinext: App Router and Server Actions work by default—no configuration needed.
Troubleshooting
Config Not Loading
Problem: Changes to next.config.js aren’t reflected
Solution: Restart the dev server. Config is loaded once at startup.
Path Alias Not Working
Problem: Import using @/... fails
Solution: Ensure tsconfig.json has correct paths config and baseUrl is set.
PostCSS Error
Error: Error: Cannot find module 'postcss.config.js'
Solution: Rename to postcss.config.cjs if your project has "type": "module" in package.json.
Environment Variable Not Available
Problem: process.env.MY_VAR is undefined in client code
Solution: Client-side variables must start with NEXT_PUBLIC_:
Next Steps
Deployment
Deploy your configured application
Cloudflare Workers
Deploy to Cloudflare with advanced config
Static Export
Configure static site generation
Vite Documentation
Complete Vite configuration reference