Projects BibleWeb Interlinear Personal gloss selection (persist)
Done

Personal gloss selection (persist)

Area: Interlinear Milestone: v2

Context

Problem: Users who explore alternative glosses in the interlinear popup want their choices remembered. Without persistence, selections are lost when the popup closes.

Solution: Two-layer persistence — localStorage for instant offline access, server-side for authenticated users. Selections merge with server data winning on conflict.

Not included: Cloud sync between accounts or sharing selections.

Functional

Selections are saved immediately and restored when reopening the popup for the same verse.

User flow:

  1. User selects a gloss → saved instantly to localStorage
  2. Close popup → reopen later → selection restored
  3. If authenticated: also saved to server via API
  4. On another device (authenticated): server selections loaded and merged

Merge: Server wins over localStorage on conflict.

UX & Design

Invisible persistence — users just see their selections restored.

Visual indicators: Selected word cards get word-card--selected class + badge. Composed translation bar at bottom updates.

Technical

localStorage: Key bibleweb_translationsRecord<"bookId-chapter-verse-wordPosition", gloss>

Server: GET/POST/DELETE /api/word-selections/{bookId}/{chapter}/{verse}

DB: word_selections — unique on (userId, bookId, chapter, verse, wordPosition), upsert on conflict.

Files:

  • apps/web/src/lib/components/bible/InterlinearPopup.svelte — load/save logic
  • apps/web/src/routes/api/word-selections/[bookId]/[chapter]/[verse]/+server.ts
  • apps/web/src/lib/server/queries/word-selections.ts

Status

Current: DONE Milestone: v2 Priority: Core — without persistence, gloss selection is useless

Dependencies:

  • Requires: multiple gloss options (DONE), word_selections table (DONE)