Every story node in The Beach Mystery carries aDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/apursley2012/the-beach-mystery/llms.txt
Use this file to discover all available pages before exploring further.
scene field — a short string key like "beach" or "cave-fork" — that tells the app which illustration to display while that node’s text is on screen. The lookup happens in data/sceneImages.js, which maps each key to a PNG filename and a descriptive alt text string. Vite resolves those filenames into fingerprinted, production-ready URLs at build time, so adding or swapping an illustration is as simple as editing the map and dropping a file into the right folder.
How sceneImages.js Works
The file builds its URL map with a small helper function:
new URL(path, import.meta.url).href pattern is the Vite-idiomatic way to reference static assets from JavaScript. Vite detects these calls during the build, copies the referenced files into dist/, appends a content-hash to each filename (fingerprinting), and rewrites the href value to the hashed path. You never need to manage asset paths manually.
Two or more scene keys can share the same PNG file — for example,
chest and chest-open both point to buried-treasure-chest.png, and island, island-path, and riddle all use treasure-island.png. This is intentional: the scene key captures narrative context while the image file is the shared visual.Complete Scene Key → Filename Map
| Scene key | PNG file | Used by nodes |
|---|---|---|
beach | beach-shore.png | beachOpening |
chest | buried-treasure-chest.png | chestDiscovery, chestChoice |
chest-open | buried-treasure-chest.png | chestOpened |
beach-walk | beach-shore.png | chestSkipped, skipMap |
map | treasure-map.png | mapChoice |
island | treasure-island.png | followMap |
island-path | treasure-island.png | riddleSolved |
riddle | treasure-island.png | riddleIntro |
cave-entrance | cave-entrance.png | caveChoiceWithJewel, caveChoiceWithoutMap |
cave-interior | dark-cave.png | caveEnteredWithJewel, caveEnteredWithoutJewel |
cave-fork | cave-fork.png | cavePathChoiceWithJewel, cavePathChoiceWithoutJewel |
treasure-chamber | hidden-cave-treasure.png | caveLeftWithJewel, caveLeftWithoutJewel |
animal-den | magical-creature-den.png | caveRightWithJewel, caveRightWithoutJewel |
beach-sunset | beach-sunset.png | caveSkippedWithJewel, caveSkippedWithoutJewel |
Replacing an Existing Illustration
Prepare your new image
Create your replacement PNG. A 16:9 aspect ratio is recommended — the
feature-card__art CSS rule crops to this ratio on the gallery and storyline screens. Any resolution is fine; images are lazy-loaded so large files do not block the initial render.Name the file something descriptive, for example beach-shore-v2.png.Drop it into assets/story-art/
Copy the file to
assets/story-art/ at the root of the repository. This is the only directory Vite scans for scene art.Update the map entry in sceneImages.js
Change the filename string inside the You can update the
a() call for the relevant key:alt text at the same time if the new image depicts the scene differently.Adding a New Scene
Add your PNG to assets/story-art/
Place the new file in
assets/story-art/. Choose a filename that matches the visual content, for example lighthouse-cliff.png.Register it in sceneImages.js
Add a new key to the
s object. The key should be a short, hyphenated string that describes the narrative moment — this is what story authors will write in the scene field of their nodes.The SceneArt Component
Story nodes do not render images directly — they delegate to theSceneArt component, which handles loading, fallback, and overlay behaviour.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
scene | string | — | Scene key looked up in sceneImages.js. Falls back to 'beach' if the key is not found. |
size | 'small' | 'large' | 'large' | Applies scene-art--small or scene-art--large CSS modifier class. |
Rendered structure
aria-hidden="true" attribute marks the entire artwork container — including the img inside it — as decorative. The whole subtree is hidden from the accessibility tree, so screen readers will not announce the alt text. The alt strings in sceneImages.js are still present in the markup for maintainability and tooling, but they are not read aloud during play because the surrounding narrative text already describes the scene.
Error handling
If a PNG fails to load (broken path, network error, missing file), theonError handler hides the img element and displays the fallback div with a 🏖️ emoji instead. The story remains fully playable — artwork is decorative, not functional.
Image Recommendations
Format
PNG is the standard format used throughout the project. SVG files are also supported — add the
.svg extension in the a() call and the rest of the pipeline is identical.Aspect ratio
16:9 is recommended. The
feature-card__art CSS rule applies this ratio on gallery and feature-card views. Tall or square images will be cropped by the browser.Resolution
Any resolution is accepted. Images are lazy-loaded, so high-resolution files do not delay the initial page load. Vite copies them as-is; no resizing occurs at build time.
Alt text
Write alt text in
sceneImages.js, not in JSX. This centralises accessibility strings and ensures every use of the same image inherits the same description. Be specific — describe what the illustration shows.