Share Links (Game + Guess the Move)
Dice Chess Trainer supports two share flows:
- Game position sharing from View/Train game playback.
- Puzzle sharing from Practice mode (Guess the Move).
Both flows produce a public Open Graph landing page and then redirect to the PWA.
How to share
Section titled “How to share”Click 🔗 Share in the top navigation bar.
| Environment | Behaviour |
|---|---|
| Mobile / installed PWA | Opens the native OS share sheet (navigator.share) |
| Desktop browser | Copies the link to clipboard; a toast confirms success |
The generated URL depends on current mode:
- Game playback:
/api/share/{game_id}?move={move_index} - Practice mode:
/api/share/puzzle/{puzzle_id}
Flow A: Share game position
Section titled “Flow A: Share game position”sequenceDiagram
actor User
participant PWA as Frontend PWA
participant Share as /api/share/:gameId
participant Games as /api/games/:gameId/preview.png
User->>PWA: Click Share at move N
PWA-->>User: /api/share/<gameId>?move=N
User->>Share: Open link
Share-->>User: HTML with og:* + JS redirect
Note over User: Social crawler fetches preview
User->>Games: GET /api/games/<gameId>/preview.png?move=N
Games-->>User: board image
User->>PWA: /?game=<gameId>&move=N
PWA-->>User: game opened at move N
Flow B: Share puzzle (Guess the Move)
Section titled “Flow B: Share puzzle (Guess the Move)”sequenceDiagram
actor User
participant PWA as Frontend PWA
participant Share as /api/share/puzzle/:puzzleId
participant Public as /api/v1/training-puzzles/:puzzleId/*
User->>PWA: Click Share in Practice mode
PWA-->>User: /api/share/puzzle/<puzzleId>
User->>Share: Open link
Share-->>User: HTML with og:* + JS redirect
Note over User: Social crawler fetches preview
User->>Public: GET /api/v1/training-puzzles/<id>/preview.png
Public-->>User: PNG (or SVG fallback)
User->>PWA: /?puzzle=<puzzleId>
PWA->>Public: GET /api/v1/training-puzzles/<id>/public
Public-->>PWA: puzzle payload
PWA-->>User: isolated Guess the Move screen
Frontend Entry Logic
Section titled “Frontend Entry Logic”App.svelte checks window.location.search for puzzle during onMount.
If present:
- Render
SharedPuzzleViewdirectly. - Skip the main navigation shell.
- Do not run normal game URL sync (
game/move) effects.
This guarantees a single-purpose public screen.
SharedPuzzleView Behavior
Section titled “SharedPuzzleView Behavior”SharedPuzzleView is intentionally limited:
- Loads only one puzzle via
ApiClient.getPublicPuzzle(puzzleId). - Renders board + dice +
Reset/Check Answer. - Validates by board-part FEN equality (same strategy as practice mode).
- If incorrect, replays solution moves visually.
- No “next puzzle”, no bookmarks, no settings/admin navigation.
Backend share endpoints
Section titled “Backend share endpoints”/api/share/{game_id}
Section titled “/api/share/{game_id}”- Returns minimal HTML with
og:title,og:description,og:image,twitter:card. - Redirects to
/?game={game_id}&move={move}. og:imagepoints to/api/games/{game_id}/preview.png.
/api/share/puzzle/{puzzle_id}
Section titled “/api/share/puzzle/{puzzle_id}”- Returns minimal HTML with puzzle-specific OG metadata.
- Redirects to
/?puzzle={puzzle_id}. og:imagepoints to/api/v1/training-puzzles/{puzzle_id}/preview.png.- When linked puzzle has
game_id, metadata includes players and ratings.
Preview image generation
Section titled “Preview image generation”Game previews
Section titled “Game previews”- Endpoint:
/api/games/{game_id}/preview.png - Source:
gameMoveHistoryStateMap[move](fen, dice, clocks) - Render path:
fen_to_svg(...)->cairosvg.svg2png(...)
Puzzle previews
Section titled “Puzzle previews”- Endpoint:
/api/v1/training-puzzles/{puzzle_id}/preview.png - Source:
TrainingPuzzle.normalized_initial_fen+ puzzle dice + optional game metadata - Render path: High-quality
python-chessSVG board composited into a standard layout with player metadata and unicode dice symbols ->cairosvg.svg2png(...) - Fallback: if cairo is missing at runtime, endpoint returns
image/svg+xml
Frontend share button rules
Section titled “Frontend share button rules”TopNavigationBar.svelte decides share type at click time:
- If practice mode is active and
currentPuzzle.idexists -> share puzzle URL. - Otherwise -> share game URL with current move index.
No API request is needed to build the URL.
Key Files
Section titled “Key Files”frontend-pwa/src/App.sveltefrontend-pwa/src/views/SharedPuzzleView.sveltefrontend-pwa/src/components/TopNavigationBar.sveltefrontend-pwa/src/lib/api/client.tsbackend-api/src/dicechess_trainer/routers/share.pybackend-api/src/dicechess_trainer/routers/training.py