Vite Integration
Dodeca integrates with Vite for seamless frontend development. When a Vite configuration is detected, dodeca automatically starts the Vite dev server and proxies requests to it.
How it works
When you run ddc serve, dodeca:
- Checks for a Vite configuration file at your project root
- Runs
pnpm installif needed - Starts
pnpm run devto launch the Vite dev server - Proxies matching requests from the dodeca server to Vite
- Proxies WebSocket connections for Hot Module Replacement (HMR)
This means you get a single ddc serve command that handles both your static site and your frontend assets with full HMR support.
Setup
1. Create Vite configuration
Add a vite.config.ts (or .js, .mts, .mjs) at your project root:
// vite.config.ts
import { defineConfig } from 'vite'
export default defineConfig ({
// Your Vite configuration
})
2. Add package.json with dev script
Create a package.json with the standard Vite dev script:
{
"name" : "my-site" ,
"scripts" : {
"dev" : "vite" ,
"build" : "vite build"
},
"devDependencies" : {
"vite" : "^5.0.0"
}
}
3. Install dependencies
pnpm install
4. Run dodeca
ddc serve
You should see output indicating the Vite server is starting:
Starting Vite dev server in /path/to/project
[vite] VITE v5.x.x ready
OK Vite dev server running on port 5173
Directory structure
A typical project with Vite might look like:
my-site/
├── .config/
│ └── dodeca.yaml
├── content/
│ └── index.md
├── templates/
│ └── base.html.jinja
├── static/ # Hand-crafted static assets
│ └── favicon.ico
├── dist/ # Generated assets (Vite build output)
│ └── assets/
│ ├── main-abc123.js
│ └── style-def456.css
├── src/ # Frontend source (Vite)
│ ├── main.ts
│ └── style.css
├── package.json
├── pnpm-lock.yaml
└── vite.config.ts
Note: The dist/ directory is for generated/build output and should be gitignored. Files in dist/ take priority over files in static/ when paths conflict.
Proxied paths
Dodeca proxies the following requests to Vite:
/@vite/*- Vite client scripts/@id/*- Module IDs/@fs/*- File system access/@react-refresh- React Fast Refresh runtime/node_modules/.vite/*- Pre-bundled dependencies/node_modules/*- Node modules*.ts,*.tsx,*.jsx,*.vue,*.svelte- Source files*.hot-update.json,*.hot-update.js- HMR updates
All other requests go through dodeca's normal content handling.
HMR (Hot Module Replacement)
WebSocket connections for HMR are automatically proxied. This means:
- CSS changes apply instantly without page reload
- JavaScript/TypeScript changes hot-reload (with framework support)
- You get Vite's fast feedback loop while keeping dodeca's live reload for content
Using in templates
Reference your Vite-built assets in templates. In development, Vite serves them directly:
<!-- In development, Vite serves this with HMR -->
< script type ="module " src ="/src/main.ts "></ script >
For production builds, you'll want to use Vite's build output. See the Production section below.
Production builds
When you run ddc build, dodeca automatically:
- Detects
vite.config.ts(or variant) at project root - Runs
pnpm installif needed - Runs
pnpm run buildto build frontend assets - Then proceeds with the normal dodeca build
Configure Vite to output to the dist/ directory:
// vite.config.ts
import { defineConfig } from 'vite'
export default defineConfig ({
build : {
outDir : 'dist' , // Output to dodeca's dist directory
manifest : true , // Generate manifest for asset references
}
})
The built assets in dist/ are automatically included in dodeca's output. Remember to add dist/ to your .gitignore since these are generated files.
Dev vs Production assets
You can reference source files directly - dodeca automatically rewrites them to the built output in production:
<!-- Works in both dev and production -->
< script type ="module " src ="/src/main.ts "></ script >
In development, Vite serves /src/main.ts directly with HMR. In production (ddc build), dodeca reads the Vite manifest at dist/.vite/manifest.json and automatically rewrites /src/main.ts to /assets/main-abc123.js.
This means you don't need conditional logic in your templates - the same markup works everywhere.
Framework examples
React
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig ({
plugins : [ react ()]
})
Vue
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig ({
plugins : [ vue ()]
})
Svelte
// vite.config.ts
import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'
export default defineConfig ({
plugins : [ svelte ()]
})
Troubleshooting
Vite not starting
- Ensure
vite.config.ts(or variant) exists at project root - Check that
pnpmis installed and in your PATH - Check that
package.jsonhas adevscript that runs Vite - Look for error messages in the terminal output
HMR not working
- Check browser console for WebSocket connection errors
- Ensure the Vite WebSocket path isn't being blocked
- Try refreshing the page to re-establish the connection
Assets not loading
- Check that the path matches one of the proxied patterns
- Look at the browser Network tab to see where requests are going
- Verify Vite is running by accessing
http://localhost:5173directly
Timeout starting Vite
Dodeca waits 30 seconds for Vite to report its port. If your pnpm install is slow:
- Pre-run
pnpm installbefore startingddc serve - Consider using
pnpm install --frozen-lockfilefor faster installs