Developer panel for inspecting and previewing the Universal Login JSON context (window.universal_login_context) for the Advanced Customizations for Universal Login (ACUL) feature.
- Detects if a real tenant context exists ("connected" mode).
- If not, lets you preview screens & variants using a local or CDN manifest ("disconnected" mode).
- Lets you inspect & live-edit mock context JSON (broadcasts a custom event).
- Persists your selections (screen / variant / data source / version) in
sessionStoragebetween reloads.
npm install @auth0/ul-context-inspectorPeer dependencies (install if you donβt already have them):
npm install react react-domWhen the panel runs in disconnected mode it attempts to fetch a local manifest at GET /manifest.json:
- If the request succeeds (HTTP 200), the data source switches to "Local development" automatically.
- If it fails, the panel defaults to the Auth0 CDN manifest.
Place your manifest and variant JSON under public/ so Vite (or your bundler) serves them from the root:
public/
manifest.json
screens/
login/
login/
default.json
with-errors.json
login-id/
login-id/
default.json
with-errors.json
manifest.json contains an array screens with objects mapping prompt β screen β variant node:
Each variant file is loaded at: <path>/<variant>.json (e.g. /screens/login/login/default.json).
If a node omits variants, the panel assumes a single default variant.
import { UniversalLoginContextPanel } from '@auth0/ul-context-inspector';
export function App() {
return <UniversalLoginContextPanel defaultScreen="login:login" />;
}defaultScreen uses prompt:screen format. If omitted and CDN mode is active, the panel may auto-select a common screen (e.g. login-id:login-id).
Use the subscription hook if your host needs to re-render on context changes:
import { useUniversalLoginContextSubscription } from '@auth0/ul-context-inspector';
function Host() {
const context = useUniversalLoginContextSubscription();
return <pre>{JSON.stringify(context?.screen, null, 2)}</pre>;
}- Connected mode: If
window.universal_login_contextexisted at mount, selections do not override real tenant context screen/variant. - Disconnected mode: Screen & variant selection reloads the page to simulate host SDK remount.
- Persistence: Values stored in
sessionStoragewith prefixulci:. - Local manifest auto-detection runs once at startup; if found, data source switches to Local.
- Editing JSON: Writes directly to
window.universal_login_context(even in mock mode) and triggers a broadcast event.
| Prop | Type | Default | Description |
|---|---|---|---|
defaultScreen |
string |
undefined |
Initial preview screen (prompt:screen) if no prior session selection. |
Tailwind classes are prefixed with uci-. If you purge CSS, safelist with a regex like /uci-/.
npm install
npm run dev # Start dev server
npm run build # Produce dist (JS, types, CSS)This project follows Conventional Commits specification. All commit messages must be structured as follows:
<type>: <description>
[optional body]
[optional footer]
- feat: A new feature
- fix: A bug fix
- docs: Documentation only changes
- style: Changes that don't affect code meaning (whitespace, formatting)
- refactor: Code change that neither fixes a bug nor adds a feature
- perf: Performance improvements
- test: Adding or updating tests
- chore: Changes to build process or auxiliary tools
feat: add search functionality to context inspector
fix: resolve memory leak in subscription hook
docs: update installation instructions
refactor: simplify manifest loading logicCommits are validated using commitlint. Invalid commit messages will be rejected by the pre-commit hook.
Why is my local manifest ignored?
Ensure public/manifest.json returns 200 and matches the shape above; check dev tools Network panel.
How do I force CDN mode?
Delete/rename local manifest.json or manually switch data source in the panel.
Apache-2.0

{ "screens": [ { "login": { "login": { "path": "/screens/login/login", "variants": ["default", "with-errors"] } } }, { "login-id": { "login-id": { "path": "/screens/login-id/login-id", "variants": ["default", "with-errors"] } } } ] }