Installation overview
There are two paths to a working Flexweg CMS, depending on whether you're a developer who wants to build the admin yourself, or a user who's been given a pre-built dist/ to drop on Flexweg.
Both end up with the same admin running on your Flexweg site, configured against your own Firebase project. The difference is purely how you get the bundle and where you fill in credentials.
Path A — No-build deployment (recommended for non-developers)
Best when:
- Someone has already produced a
dist/admin/for you (a release, a colleague, …) - You don't have Node.js installed and don't want to install it
- You only want to run the admin, not modify it
Steps:
- Set up Firebase — create the project, enable Authentication + Firestore
- Configure Firestore rules — paste the rules with your admin email
- Set up Flexweg — get an API key, configure allowed extensions
- Upload
dist/admin/to a folder on your Flexweg site (typically/admin/) - Upload
dist/theme-assets/to the site root - Run the in-admin setup form — fill Firebase + Flexweg credentials in a wizard
The wizard validates everything (signs in to Firebase, tests the Flexweg API, writes Firestore, uploads a populated config.js) and reloads. You're logged in.
→ Quick start guide walks through this end-to-end with screenshots.
Path B — Local build with .env
Best when:
- You're a developer working on plugins, themes, or the admin itself
- You want HMR via
npm run dev - You want to bake credentials into the build instead of using the wizard
Steps:
- Set up Firebase — same as Path A
- Configure Firestore rules — same as Path A
- Set up Flexweg — same as Path A
- Clone the repo,
cp .env.example .env, fill inVITE_FIREBASE_*+VITE_ADMIN_EMAIL - Local development — run
npm install --legacy-peer-deps && npm run devto develop, ornpm run build && upload dist/admin/to deploy
When the build has .env filled, config.js is baked with values at build time and the in-admin setup form never appears.
Path C — Hybrid
It's totally fine to develop locally with a .env and also distribute pre-built dists to non-developers. The admin works either way. Internally:
- If
import.meta.env.VITE_FIREBASE_API_KEYis set at build time → values are baked into the bundle,config.jsships as a no-op - If not set at build time → bundle reads
window.__FLEXWEG_CONFIG__(set byconfig.js); the in-admin setup form fillsconfig.json first run
That's the same code path. You can switch back and forth freely; the admin auto-detects which mode it's in.
What you need before you start
| Path A (no-build) | Path B (local) | |
|---|---|---|
| Flexweg account | ✓ | ✓ |
| Google account (for Firebase) | ✓ | ✓ |
Pre-built dist/admin/ | ✓ | (built locally) |
| Node.js 20+ | ✗ | ✓ |
| Git | ✗ | ✓ |
| ~15 minutes | ✓ | ~30 minutes |
What gets deployed where
Your Flexweg site
├── / ← public site root
│ ├── index.html ← published home (after first publish)
│ ├── <category>/<post>.html ← published posts
│ ├── theme-assets/ ← uploaded from dist/theme-assets/
│ │ └── <theme-id>.css ← active theme's CSS
│ ├── media/yyyy/mm/ ← uploaded images (auto-resized variants)
│ ├── menu.json ← header + footer menu data
│ └── posts.json ← search-related JSON if flexweg-search is on
│
└── /admin/ ← admin SPA (uploaded from dist/admin/)
├── index.html
├── config.js ← Firebase config (filled at first-run)
├── external.default.json ← bundled plugins/themes baseline
├── assets/ ← admin bundle, fonts, images
├── runtime/ ← runtime stubs for external bundles
├── plugins/<id>/ ← per-plugin compiled bundles
└── themes/<id>/ ← per-theme compiled bundles
The /admin/ folder is fully redeployable — you can rewrite it on every admin upgrade without losing user state, because installed plugins / theme settings / posts all live in Firestore.
Continue reading
- Firebase project setup — the first step, regardless of path
- Quick start — Path A end-to-end with copy-pasteable values
- Local development — Path B for developers