Embed an idiomatic Bevy app inside your Leptos app.
BevyCanvas component.Resources with RwSignals in your Leptos app.Querys with RwSignals in your Leptos app.States with RwSignals in your Leptos app.use bevy::prelude::*;
use leptos::prelude::*;
use leptos_bevy_canvas::prelude::*;
#[derive(Message)]
pub struct TextMessage {
pub text: String,
}
#[component]
pub fn App() -> impl IntoView {
// This initializes a sender for the Leptos app and
// a receiver for the Bevy app
let (text_message_sender, bevy_text_receiver) = message_l2b::<TextMessage>();
let on_input = move |evt| {
// send the message over to Bevy
text_message_sender
.send(TextMessage { text: event_target_value(&evt) })
.ok();
};
view! {
<input type="text" on:input=on_input />
<BevyCanvas
init=move || {
// Pass the receiver into the Bevy app initialization
init_bevy_app(bevy_text_receiver)
}
{..}
width="300"
height="500"
/>
}
}
// In Bevy it ends up just as a normal message
pub fn set_text(
mut message_reader: MessageReader<TextMessage>,
) {
for message in message_reader.read() {
// do something with the message
}
}
// This initializes a normal Bevy app
fn init_bevy_app( text_receiver: BevyMessageReceiver<TextMessage>) -> App {
let mut app = App::new();
app
.add_plugins(
DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window {
// "#bevy_canvas" is the default and can be
// changed in the <BevyCanvas> component
canvas: Some("#bevy_canvas".into()),
..default()
}),
..default()
}),
)
// import the message here into Bevy
.import_message_from_leptos(text_receiver)
.add_systems(Update, set_text);
app
}
Please check the examples to see how to synchronize a Resource or a Query.
| Crate version | Compatible Leptos version | Compatible Bevy version |
|---|---|---|
| 0.6 | 0.8 | 0.19 |
| 0.5 | 0.8 | 0.18 |
| 0.4 | 0.8 | 0.17 |
| 0.3 | 0.8 | 0.16 |
| 0.1, 0.2 | 0.7 | 0.15 |
$ claude mcp add leptos-bevy-canvas \
-- python -m otcore.mcp_server <graph>