Troubleshooting
A guided tour of the failure modes we've seen, in rough order of frequency.
"My layout collapses when I switch packs."
Almost always one of:
1. You wrote structural CSS into the theme pack
The new pack doesn't have those rules; the page falls back to default
styling. See Structure vs. style — the
fix is to move structural CSS into your project's static/css/input.css.
2. You hard-coded a hex color in CSS
Hex doesn't move when the pack changes. Grep your stylesheets:
grep -nE '#[0-9a-fA-F]{3,8}' static/css/input.css
Replace with hsl(var(--…)) references to the appropriate token. See
Tokens for the vocabulary.
3. Your Tailwind output is stale
If you're using Tailwind, rebuild after editing input.css:
make tailwind-build
In dev with make tailwind-watch running, this happens automatically —
but a stopped watcher leaves you with a stale output.css.
"The new pack's colors don't show up at all."
1. Your stylesheet's :root overrides win
If your static/css/input.css declares :root { --primary: …; }, that
takes precedence over the pack's emitted variable because cascade order
favors the later rule. Either remove the override (use the pack's
value) or scope it (.theme-marketing { --primary: …; }) per
Recipes.
2. Pack registration didn't run
Confirm the pack is registered:
from djust.theming import get_registry
print('sunset' in [p.name for p in get_registry().list_packs()])
If False, your apps.py:ready() hook isn't running. Check
INSTALLED_APPS, restart the dev server.
3. Pack name typo in settings
LIVEVIEW_CONFIG['theme']['pack'] is case-sensitive. djust falls back
to the default pack with a warning if the name doesn't match a
registered pack. Check the dev console for:
W001 Theme pack 'sunsey' not registered; falling back to 'shadcn'.
"Pack switch doesn't persist."
1. persist_in_session is False
Check LIVEVIEW_CONFIG['theme']['persist_in_session']. Default is
True; if you've turned it off, the choice only applies for the
current page render.
2. Sessions aren't enabled
django.contrib.sessions must be in INSTALLED_APPS and the session
middleware must be in MIDDLEWARE. djust depends on Django's session
machinery to persist the choice.
3. Two djust projects on the same shared domain
Browsers scope cookies by domain (not port). If you run docs.djust.org
on :8003 and your demo on :8001, they fight over the same cookie.
Set cookie_namespace on each — see
Runtime switching.
"Mode toggle doesn't appear in the theme panel."
LIVEVIEW_CONFIG['theme']['enable_dark_mode'] = False hides the mode
toggle. Set to True to expose it.
The pack must also define both light and dark token sets — packs
that only define one mode hide the toggle automatically.
"FOUC — wrong theme flashes on page load."
The active pack is rendered server-side, so the initial paint is correct. FOUC comes from one of:
1. Your base template doesn't include the anti-FOUC inline <script>
djust's shipped base templates include a small <head> script that
syncs localStorage to the cookie before first paint. If you wrote your
own base template, copy the pattern from
djust/templates/djust_theming/_anti_fouc.html.
2. The CSS variable block is loaded after the body content
The <style> block djust emits with the active tokens needs to be in
<head>, before any user-visible content. Confirm your base template
puts {% theme_css %} (or the equivalent context-processor render) in
<head>.
"Components look wrong but the colors are right."
Components inherit the theme's design system (typography, layout,
animation, interaction) in addition to colors. If the shape looks
wrong (button radius, focus ring style, density), check that the
DesignSystem in the active pack matches what you expect.
To see the active design system:
from djust.theming import get_active_pack
pack = get_active_pack(request)
print(pack.design_theme) # 'shadcn', 'editorial', 'material', …
If a pack mixes a custom preset with a shipped design system, swapping the design system independently is one fix; authoring a pack with the right design system is another.
"I want to know exactly which CSS variables are emitted right now."
The dev panel at /_djust/panel/ (when DEBUG=True) has a Theming
tab that shows the full token table for the active pack and mode. Copy
any value from there to use in custom CSS.
For programmatic access:
from djust.theming.css_generator import generate_pack_css
print(generate_pack_css('docs', mode='dark'))
Returns the exact CSS string djust would inject for that pack and mode.
"Switching packs is slow."
Pack swap is a session write + a per-request CSS regeneration. The CSS regeneration is in-memory and sub-millisecond — the latency is dominated by your session backend (Redis < cookie < DB). If you see real latency, profile your session writes.
See also
- Settings — verify
pack,default_mode,persist_in_session,enable_dark_modeagainst this checklist. - Structure vs. style — the most common failure mode, in detail.
- Tokens — the canonical variable reference.