- JavaScript 33.1%
- Makefile 31.6%
- Go 19.9%
- TypeScript 13.1%
- Vue 2.3%
|
|
||
|---|---|---|
| .forgejo/workflows | ||
| .meta | ||
| templates | ||
| utils | ||
| workflows/pocketbase | ||
| .gitignore | ||
| bun.lock | ||
| index.js | ||
| package.json | ||
| README.md | ||
Nurev
Template generator for Nuxt configured with “on-demand revalidation” and support for multiple backends (WIP)
Available backends
How to use it?
- Run the script
bunx nurev
npx nurev
pnpm dlx nurev
- After the script completes, start the backend in dev mode
make backend-dev
- Then start frontend in dev mode
make frontend-dev
How it works?
- Interactive prompts: Asks you to choose a package manager (
bun,npm, orpnpm) and a backend (PocketBase) - Template copying: Copies the base Nuxt template, backend-specific files, and package-manager-specific configuration to your current directory
- Installation & setup: Runs
make installto install dependencies andmake setupto initialize the project - Backend configuration: Applies backend-specific setup (e.g., PocketBase configuration)
- Ready to use: Your Nuxt project with on-demand revalidation is ready
On-Demand Revalidation
The caching system uses a webhook pattern between PocketBase and Nuxt:
-
Cache storage: Nuxt routes use
defineCachedEventHandlerwithswr: true(stale-while-revalidate) andmaxAge: 604800(1 week). Route rules setprerender: truefor/andswr: truefor/posts/** -
Backend hooks: Backend (PocketBase) registers hooks on
OnRecordAfterCreateSuccess,OnRecordAfterUpdateSuccess,OnRecordAfterDeleteSuccess,OnBackupCreateandOnBackupRestorefor collections defined inTABLES_TRIGGER -
Webhook notification: When a record changes, PocketBase sends an authenticated POST (JWT Bearer token) to
/api/private/reloadcachewith the table name and record ID -
Selective invalidation: The Nuxt endpoint validates the JWT and uses
useStorage("cache")to remove only cache entries matching the changed table and record ID. Backup events trigger a full cache clear -
Next request: Subsequent requests fetch fresh data and repopulate the cache
Pros and Cons
Pros
- ⚡ Performance: Cached responses are served instantly without hitting the database on each request
- 📉 Reduced backend load: Fewer API calls to PocketBase, lowering server resource usage
- 🔄 Fresh data on demand: Cache is invalidated only when data actually changes, avoiding stale content
- 🚀 Scalability: SWR (stale-while-revalidate) serves cached content while refreshing in the background, keeping response times low under high traffic
Cons
- 🔗 Tight coupling: The backend must know the frontend URL and send webhooks, creating a dependency between services
- 🌐 Network reliability: If the webhook fails to reach Nuxt (network issues, downtime), the cache won't be invalidated and stale data persists
- 🖥️ Single-server limitation: Cache is stored in-memory/local storage, so this approach doesn't work well with multi-instance deployments without a shared cache layer (e.g., Redis)
- ⚙️ Complexity: Requires configuring JWT secrets, environment variables, and ensuring both services are running and communicating correctly