Svelte Components
Svelte Components
Section titled “Svelte Components”FrontMark can compile Svelte sources into a small client bundle and mount them from Markdown with a ::: svelte directive.
The directive passes configuration as component props. Hyphenated attributes are converted to camelCase, so supabase-url becomes supabaseUrl and button-text becomes buttonText.
Build Commands
Section titled “Build Commands”| Command | Action |
|---|---|
make svelte | Compile svelte-components/src/** into public/svelte/. |
make svelte_watch | Rebuild the Svelte bundle when component sources change. |
make svelte_test | Build the site and verify the Svelte docs page with Playwright. |
make build | Compile Svelte, rebuild tags and build Astro. |
make preview | Build everything and preview the production output. |
The Docker image uses npm run build, so the Svelte bundle is compiled inside the build stage before Astro writes dist/.
Modal Component
Section titled “Modal Component”The modal component can display Markdown/HTML passed inside the directive.
::: svelte { component=modal title="FrontMark modal" button-text="Open modal" width="min(34rem, 92vw)" }
<p><strong>Svelte receives this HTML from Markdown.</strong></p>
<p>The component can also load remote HTML with the `url` prop.</p>
:::
Svelte receives this HTML from Markdown.
The component can also load remote HTML with the `url` prop.
:::Svelte receives this HTML from Markdown.
The component can also load remote HTML with the `url` prop.
:::Modal From URL
Section titled “Modal From URL”Use url when the modal must fetch content only when it opens.
::: svelte { component=modal title="Wikipedia: Markdown" button-text="Open Wikipedia article" url="https://en.wikipedia.org/api/rest_v1/page/html/Markdown" width="min(54rem, 94vw)" }
:::
Supabase Props
Section titled “Supabase Props”The example Supabase components do not hardcode the project URL or anon key. Pass them from Markdown:
supabase-url="https://supabase.newkube.ia86.cc"supabase-anon-key="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJyb2xlIjogImFub24iLAogICJpc3MiOiAic3VwYWJhc2UiLAogICJpYXQiOiAxNzQwMTc4ODAwLAogICJleHAiOiAxODk3OTQ1MjAwCn0.omZ615aeCi9LuWt5fforhMYeoaFEshFgCutMkOqY9xw"The map component uses local icon definitions from /icons/icons.json by default. The matching marker image is /icons/marker.png. Override icons-url and marker-url when a project ships its own icon set. FrontMark also bundles the matching custom IcoFont font so table and statistics icons render from <i class="icofont-..."> tags.
Supabase Map
Section titled “Supabase Map”Live Supabase rendering
Section titled “Live Supabase rendering”This result calls Supabase directly from the browser with the public anon key passed by Markdown. The department prop is set explicitly so the example works on localhost and on preview domains.
::: svelte { component=supabase-map supabase-url="https://supabase.newkube.ia86.cc" supabase-anon-key="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJyb2xlIjogImFub24iLAogICJpc3MiOiAic3VwYWJhc2UiLAogICJpYXQiOiAxNzQwMTc4ODAwLAogICJleHAiOiAxODk3OTQ1MjAwCn0.omZ615aeCi9LuWt5fforhMYeoaFEshFgCutMkOqY9xw" department="lot" height=380 }
:::
Production source
Section titled “Production source”::: svelte { component=supabase-map supabase-url="https://supabase.newkube.ia86.cc" supabase-anon-key="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJyb2xlIjogImFub24iLAogICJpc3MiOiAic3VwYWJhc2UiLAogICJpYXQiOiAxNzQwMTc4ODAwLAogICJleHAiOiAxODk3OTQ1MjAwCn0.omZ615aeCi9LuWt5fforhMYeoaFEshFgCutMkOqY9xw" domain-suffix=".example.org" department="lot" icons-url="/icons/icons.json" marker-url="/icons/marker.png" detail-url-template="~detail?id={id}" height="620px"}:::Useful props:
| Prop | Default | Purpose |
|---|---|---|
department | Derived from domain-suffix | Department name used in Supabase queries. |
department-table | departement | Table storing the map center and zoom. |
department-center-order | lng-lat | Order used by the departement.zoom field. |
geojson-rpc | get_geojson_by_department | RPC returning GeoJSON features. |
coordinates-order | lat-lng | Use lng-lat for standard GeoJSON coordinates. |
icons-url | /icons/icons.json | JSON file mapping POI types to Leaflet glyph icons. |
marker-url | /icons/marker.png | Marker bitmap used behind glyph icons. |
detail-url-template | ~detail?id={id} | Popup URL template. |
Supabase Table
Section titled “Supabase Table”Live Supabase rendering
Section titled “Live Supabase rendering”::: svelte { component=supabase-table supabase-url="https://supabase.newkube.ia86.cc" supabase-anon-key="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJyb2xlIjogImFub24iLAogICJpc3MiOiAic3VwYWJhc2UiLAogICJpYXQiOiAxNzQwMTc4ODAwLAogICJleHAiOiAxODk3OTQ1MjAwCn0.omZ615aeCi9LuWt5fforhMYeoaFEshFgCutMkOqY9xw" department="lot" page-size=5 }
:::
Production source
Section titled “Production source”::: svelte { component=supabase-table supabase-url="https://supabase.newkube.ia86.cc" supabase-anon-key="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJyb2xlIjogImFub24iLAogICJpc3MiOiAic3VwYWJhc2UiLAogICJpYXQiOiAxNzQwMTc4ODAwLAogICJleHAiOiAxODk3OTQ1MjAwCn0.omZ615aeCi9LuWt5fforhMYeoaFEshFgCutMkOqY9xw" domain-suffix=".example.org" department="lot" table-name="patrimoine" page-size=25}:::Useful props:
| Prop | Default | Purpose |
|---|---|---|
table-name | patrimoine | Supabase table to query. |
select | *, commune!inner(id, titre, departement!inner(nom)) | Supabase select expression. |
status-column | statut | Publication status column. |
published-value | publie | Value required for published rows. |
department-filter-path | commune.departement.nom | Nested filter path for the department. |
Supabase Stats
Section titled “Supabase Stats”Live Supabase rendering
Section titled “Live Supabase rendering”::: svelte { component=supabase-stats supabase-url="https://supabase.newkube.ia86.cc" supabase-anon-key="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJyb2xlIjogImFub24iLAogICJpc3MiOiAic3VwYWJhc2UiLAogICJpYXQiOiAxNzQwMTc4ODAwLAogICJleHAiOiAxODk3OTQ1MjAwCn0.omZ615aeCi9LuWt5fforhMYeoaFEshFgCutMkOqY9xw" department="lot" link-base="#" }
:::
Production source
Section titled “Production source”::: svelte { component=supabase-stats supabase-url="https://supabase.newkube.ia86.cc" supabase-anon-key="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJyb2xlIjogImFub24iLAogICJpc3MiOiAic3VwYWJhc2UiLAogICJpYXQiOiAxNzQwMTc4ODAwLAogICJleHAiOiAxODk3OTQ1MjAwCn0.omZ615aeCi9LuWt5fforhMYeoaFEshFgCutMkOqY9xw" domain-suffix=".example.org" department="lot" link-base="*trimulticritere"}:::Useful props:
| Prop | Default | Purpose |
|---|---|---|
stats-rpc | stats_patrimoine_par_departement | Main type/statistics RPC. |
particularities-rpc | stats_patrimoine_par_particularite | Particularities RPC. |
walk-rpc | stats_patrimoine_par_marche | Approach difficulty RPC. |
access-rpc | stats_patrimoine_par_acces | Access RPC. |
time-rpc | stats_patrimoine_par_time | Duration RPC. |
link-base | *trimulticritere | Base URL used for generated drill-down links. |
Source Layout
Section titled “Source Layout”svelte-components/├── vite.config.mjs└── src/ ├── index.js ├── frontmark-svelte.css ├── components/ │ ├── Modal.svelte │ ├── SupabaseMap.svelte │ ├── SupabaseTable.svelte │ └── SupabaseStats.svelte └── lib/ └── supabase.js