docs: add lnbits frontend gotchas + extension-dev reference
Two new docs to round out the lnbits-specific reference set:
docs/lnbits-frontend-gotchas.md — the Vue/Quasar UMD traps that don't
manifest under the build-step model most tutorials assume. Sections:
- No self-closing tags. UMD-loaded templates are parsed by the
browser's HTML parser, which doesn't honor self-close on non-void
elements; nesting silently breaks. Fine in .vue SFCs because the
build step rewrites them — but lnbits templates aren't SFCs.
- CSS specificity vs Quasar utilities. LNbits applies !important
overrides on .text-caption / .text-grey-*; class-based rules in
extension pages lose. Reach for inline :style bindings or static
style="" attrs instead.
- Cache busting via ?v={server_startup_time}. Bumping JS requires a
server restart; templates re-render every request.
- Dark-mode color discipline. bg-{color}-1 utilities don't get a
default text-inversion in dark theme; pair every pale background
with an explicit text class.
docs/lnbits-extension-dev.md — auth + testing + migration pattern.
Sections:
- Auth decorators table: require_invoice_key, require_admin_key,
check_admin, check_super_user. The require_admin_key vs
check_admin distinction is the most common misuse — one is
wallet-level write access (any user), the other is instance admin.
- Testing: FakeWallet for CRUD/API/UI, regtest only for real
Lightning behavior. Why the dev CLI defaults to --fakewallet.
- The migrations_fork.py pattern: keep migrations.py byte-identical
to upstream, put fork-only schema deltas in a sibling file loaded
under <ext>_fork in dbversions. Covers: architecture facts
(dbversions in core DB, no cross-DB atomicity → idempotent
migrations mandatory), squash recipe for adoption, one-time
dbversions surgery for installs that previously ran old fork
migrations, the upstream-overlap rebase scenario.
Both linked from README "Further reading". No personal identity in
either file.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0a5713c704
commit
1a75a04c2f
3 changed files with 260 additions and 2 deletions
105
docs/lnbits-frontend-gotchas.md
Normal file
105
docs/lnbits-frontend-gotchas.md
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
# 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.
|
||||
Reference in a new issue