mapo-integrations-camomilla
Nuxt module that integrates Mapo with Camomilla CMS. It works as a Nitro server-side proxy: every /api/* request from the Nuxt app is intercepted, the path is rewritten to the correct Camomilla endpoint, and the request is forwarded to the backend. Cookie handling and session sync are managed transparently.
Prerequisites
On the Django/Camomilla side:
# settings.py
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": (
"camomilla.authentication.SessionAuthentication",
# ... other classes
),
}
USE_X_FORWARDED_HOST = True # required for correct media URLsMinimum Camomilla version: django-camomilla-cms >= 5.7.1
Installation
pnpm add mapo-integrations-camomilla// nuxt.config.ts
export default defineNuxtConfig({
modules: ["mapo-integrations-camomilla"],
camomilla: {
server: "http://localhost:8000",
},
});Options
| Option | Type | Default | Description |
|---|---|---|---|
server | string | 'http://localhost:8000' | URL of the Camomilla backend |
base | string | '' | Router base prefix of your Nuxt app (e.g. '/admin') |
syncCamomillaSession | boolean | false | Enable SSO between Mapo and Django admin — see below |
forwardedHeaders | string[] | [] | Additional request headers to forward to the backend |
pathRewrite | Record<string,string> | {} | Custom path rewrites merged after the built-in ones |
changeOrigin | boolean | true | Override the Host header sent to the backend |
Path rewriting
The proxy rewrites these paths automatically. After rewriting, a deduplication pass removes any accidental double slashes that can appear when the source path already ends with / and the rewrite target also starts with /:
rewritten.replace(/([^:]\/)\/+/g, "$1");This prevents requests like /api/profiles/me/ from being rewritten to /api/camomilla//users/current/.
Rewrite table
| Nuxt app path | Camomilla backend path |
|---|---|
/api/auth/login | /api/camomilla/auth/login/ |
/api/auth/logout | /api/camomilla/auth/logout/ |
/api/profiles/me | /api/camomilla/users/current/ |
/api/media-folders | /api/camomilla/media-folders |
/api/media | /api/camomilla/media |
/api/<anything> | /api/<anything> |
Custom rewrites are merged after the defaults, so you can extend but not break the built-in mapping:
camomilla: {
server: 'http://localhost:8000',
pathRewrite: {
'^/api/custom-resource': '/api/camomilla/my-custom-resource',
}
}Cookie and session handling
The proxy manages three cookies:
| Cookie | Purpose |
|---|---|
__mapo_session | Mapo's auth token (alias for Django's sessionid) |
sessionid | Django session cookie |
csrftoken | Django CSRF token |
All other cookies are stripped from requests to the backend.
On every request
__mapo_sessionis mapped tosessionidso Camomilla recognises the Django sessioncsrftokenis forwarded as theX-CSRFTokenheader (required for POST/PUT/PATCH/DELETE)X-Forwarded-HostandX-Forwarded-Protoare derived from theRefererheader
On login / logout
- Camomilla's
sessionidresponse cookie is aliased as__mapo_session— this is how Mapo picks up the session after login - The original
sessionidcookie is stripped from the response (unlesssyncCamomillaSession: true)
syncCamomillaSession
When false (default): Mapo and Django admin have independent sessions. Logging in to Mapo does not log you into Django admin, and vice versa.
When true: both sessionid and __mapo_session are kept in sync. Logging in from either Mapo or the Django admin panel authenticates you on both sides simultaneously. Useful during development or when the same team uses both interfaces.
camomilla: {
server: 'http://localhost:8000',
syncCamomillaSession: true,
}Integration with @mapomodule/core
mapo-integrations-camomilla and @mapomodule/core are designed to work together without any glue code.
SSR proxy routing: The
@mapomodule/coreinit server plugin callsuserInfoApiusing an absolute URL (http://host/api/profiles/me/). This is required so the internal server-side$fetchcall enters Nitro's request pipeline and gets intercepted by this proxy — a relative path would bypass Nitro middleware entirely.
useMapoAuth()calls/api/auth/login→ proxy rewrites to/api/camomilla/auth/login/useCrud('/api/articles/')calls/api/articles/→ proxy forwards to/api/articles/on the backenduserInfoApi: '/api/profiles/me/'→ proxy rewrites to/api/camomilla/users/current/
// nuxt.config.ts — full example
export default defineNuxtConfig({
modules: ["mapomodule", "mapo-integrations-camomilla"],
mapo: {
authLoginUrl: "/api/auth/login",
userInfoApi: "/api/profiles/me/",
logoutUrl: "/api/auth/logout",
},
camomilla: {
server: process.env.CAMOMILLA_URL ?? "http://localhost:8000",
syncCamomillaSession: false,
},
});