105 lines
3.7 KiB
Markdown
105 lines
3.7 KiB
Markdown
# lnbits frontend gotchas
|
|
|
|
LNbits ships its UI with **Vue 3 + Quasar 2 as UMD globals** — no
|
|
build step, plain Jinja templates with per-page JS. This applies
|
|
across lnbits core (`lnbits/templates/*.html`), every extension
|
|
(`<ext>/templates/`), and every fork that doesn't restructure the
|
|
frontend stack. The UMD load model has several traps that don't
|
|
manifest under the build-step model most Vue tutorials assume.
|
|
|
|
## No self-closing tags
|
|
|
|
Per [Quasar's UMD usage rules](https://quasar.dev/start/umd/#usage),
|
|
components must use the explicit-close form:
|
|
|
|
```html
|
|
<!-- correct -->
|
|
<q-input v-model="foo" label="Foo"></q-input>
|
|
<q-btn @click="bar" label="Bar"></q-btn>
|
|
|
|
<!-- wrong — silently broken in UMD/no-build mode -->
|
|
<q-input v-model="foo" label="Foo" />
|
|
<q-btn @click="bar" label="Bar" />
|
|
```
|
|
|
|
**Why:** UMD-loaded templates are parsed by the browser's HTML parser,
|
|
not Vue's compiler. The HTML parser doesn't honor self-close on
|
|
non-void elements (per the HTML spec). The close tag gets implied at
|
|
the wrong place, nesting breaks silently, and subsequent siblings end
|
|
up nested inside the prior component.
|
|
|
|
Self-closing is fine in `.vue` SFCs (the build step rewrites them
|
|
before the browser sees anything), so if you copy a snippet from a
|
|
Vue SFC repo into an LNbits template, **expand all self-closing tags
|
|
before saving**.
|
|
|
|
## CSS specificity trap
|
|
|
|
LNbits applies its own theme overrides on Quasar's typography
|
|
utilities (`.text-caption`, `.text-grey-*`, etc.) with `!important`.
|
|
Class-based CSS rules in an extension page — *even with `!important`* —
|
|
lose this fight unless your selector is strictly more specific than
|
|
the upstream rule.
|
|
|
|
**Rule:** for per-element typography/color overrides on LNbits pages,
|
|
reach for Vue `:style` bindings (or static `style="..."` attrs), not
|
|
`<style>` blocks targeting Quasar utility classes:
|
|
|
|
```html
|
|
<!-- ✗ likely loses to upstream's !important rule -->
|
|
<style>
|
|
.text-caption.my-fix { color: #ff0000 !important; }
|
|
</style>
|
|
|
|
<!-- ✓ inline style wins without an arms race -->
|
|
<span :style="{ color: '#ff0000' }">…</span>
|
|
<span style="color: #ff0000">…</span>
|
|
```
|
|
|
|
Background/border tweaks at card-level via class are fine — the trap
|
|
is specifically the typography utilities (`text-*`) and Quasar's
|
|
color utilities.
|
|
|
|
## Cache busting
|
|
|
|
Static assets are served with `?v={server_startup_time}` appended
|
|
(see `static_url_for` in `lnbits/helpers.py`). Consequences:
|
|
|
|
- **Bumping JS requires a server restart.** Reloading the browser
|
|
doesn't help if `?v=` hasn't changed — the browser keeps serving
|
|
the cached file.
|
|
- **Jinja templates re-render on every request** (the `?v=` is only
|
|
on static assets). No restart needed for template edits — just
|
|
refresh.
|
|
|
|
If a browser keeps serving stale JS after a restart, hard-refresh
|
|
(`Ctrl+Shift+R`) to bypass the HTTP cache.
|
|
|
|
## Dark-mode color discipline
|
|
|
|
LNbits's dark theme inverts text colors on most surfaces but **not**
|
|
on `bg-{color}-1` pale-background utilities. Result: a `bg-red-1`
|
|
without an explicit text color renders white-on-cream under dark
|
|
theme — basically invisible.
|
|
|
|
**Rule:** pair every pale-background utility with an explicit dark
|
|
text class:
|
|
|
|
```html
|
|
<!-- ✗ unreadable on dark theme -->
|
|
<div class="bg-red-1 q-pa-md">Warning</div>
|
|
|
|
<!-- ✓ explicit text class survives theme switch -->
|
|
<div class="bg-red-1 text-grey-9 q-pa-md">Warning</div>
|
|
```
|
|
|
|
Same for `bg-green-1`, `bg-blue-1`, `bg-amber-1`, etc. The `text-grey-9`
|
|
choice is the safe default; pick a darker shade if you want stronger
|
|
contrast.
|
|
|
|
## When in doubt
|
|
|
|
Test under both light and dark themes (Quasar's theme toggle is at
|
|
the top of every LNbits page once you're logged in). Most of the
|
|
above gotchas are silent under one theme and obvious under the other
|
|
— don't ship UI without flipping the toggle at least once.
|