Skip to main content

autumn_plugin_svelte/
lib.rs

1//! Svelte 5 islands for Autumn, in Maud + htmx pages.
2//!
3//! The server renders an [`Island`]. The browser loader (`islands.js`)
4//! mounts a compiled Svelte component into it.
5//!
6//! ```rust,no_run
7//! use autumn_plugin_svelte::{Island, MountWhen, SveltePlugin, svelte_bundle, svelte_script};
8//! use autumn_web::assets::PluginAssets;
9//! use autumn_web::prelude::*;
10//!
11//! // Your Vite build output, compiled into the binary.
12//! static ISLANDS: PluginAssets = PluginAssets::from_files(
13//!     "app-islands",
14//!     &[("islands.js", b"/* vite build output */")],
15//! );
16//!
17//! #[get("/")]
18//! async fn index() -> AutumnResult<Markup> {
19//!     let counter = Island::new("Counter")
20//!         .props(&serde_json::json!({ "start": 3 }))?
21//!         .fallback(html! { p { "Counter: 3" } });
22//!     Ok(html! {
23//!         head { (svelte_script()) (svelte_bundle(&ISLANDS)) }
24//!         body {
25//!             (counter)
26//!             (Island::new("Chart").mount_when(MountWhen::Visible))
27//!         }
28//!     })
29//! }
30//!
31//! # async fn run() {
32//! autumn_web::app()
33//!     .plugin(SveltePlugin::new().bundle(&ISLANDS))
34//!     .routes(routes![index])
35//!     .run()
36//!     .await;
37//! # }
38//! ```
39//!
40//! The Vite entry file registers the components:
41//!
42//! ```js
43//! import { mount, unmount } from "svelte";
44//! import Counter from "./Counter.svelte";
45//!
46//! let queue = window.autumnSvelte;
47//! if (!Array.isArray(queue) && queue?.loader !== true) {
48//!   queue = window.autumnSvelte = []; // an id="autumnSvelte" element can clobber it
49//! }
50//! queue.push({ mount, unmount, components: { Counter } });
51//! ```
52//!
53//! Put user HTML in an element with `data-svelte-ignore`. The loader does not
54//! mount islands in it.
55//!
56//! # Limits
57//!
58//! - The server does not render the component. The fallback is the first
59//!   paint.
60//! - You need Node to build components. You do not need Node at run time.
61//! - Props go in an HTML attribute. Keep them small.
62
63mod assets;
64mod island;
65mod plugin;
66mod tags;
67
68pub use assets::{ASSETS_NAMESPACE, LOADER_JS, SVELTE_ASSETS};
69pub use island::{Island, JsonKind, MountWhen, PropsError};
70pub use plugin::{PLUGIN_NAME, SveltePlugin};
71pub use tags::{svelte_bundle, svelte_script};