C.W.K.
Stream
Lesson 01 of 06 · published

Creating Windows: WebviewWindow

~12 min · tauri, windows, webviewwindow, rust

Level 0Web Tourist
0 XP0/56 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"A window in config is a window you get at launch. A window in code is a window you get whenever you decide."

Two Ways to Make a Window

You can declare windows statically in tauri.conf.json (they open at startup), or create them at runtime in Rust with WebviewWindowBuilder. The static path is perfect for your main window; the runtime path is for windows you open on demand — a settings window when the user clicks Preferences, a second document window, a popup. Both produce the same WebviewWindow type.

What URL Does It Show?

A window needs to know what to render, and that's WebviewUrl. WebviewUrl::App("index.html".into()) (or a route path) loads your bundled frontend — the normal case. WebviewUrl::External(url) points the window at a remote site, which you should treat with care (see the security track on trusting remote content). WebviewUrl::default() loads your app's entry point. Most windows you create use App with a route, so the new window shows a specific screen of your own UI.

The Builder Pattern

WebviewWindowBuilder chains settings — title, size, resizability — and ends in .build(), which returns the live window (or an error). You need an AppHandle or &App to start the builder, which is why window creation usually happens in setup, in a command, or in an event handler where you have one of those in hand.

Code

Create a window at runtime, idempotently·rust
use tauri::{WebviewWindowBuilder, WebviewUrl, Manager};

// Open a settings window on demand (e.g. from a command).
#[tauri::command]
fn open_settings(app: tauri::AppHandle) -> Result<(), String> {
    // If it already exists, just focus it instead of duplicating.
    if let Some(win) = app.get_webview_window("settings") {
        let _ = win.set_focus();
        return Ok(());
    }
    WebviewWindowBuilder::new(
        &app,
        "settings",                                  // the label (identity)
        WebviewUrl::App("index.html#/settings".into()), // a route in your bundled UI
    )
    .title("Settings")
    .inner_size(520.0, 640.0)
    .resizable(false)
    .build()
    .map_err(|e| e.to_string())?;
    Ok(())
}

External links

Exercise

Add an open_settings command that creates a second window pointing at a route of your frontend (e.g. a hash route #/settings), and make it idempotent: if the window already exists, focus it instead of creating a duplicate. Wire a button to invoke it. You've built on-demand window creation, the foundation for multi-window apps.
Hint
Guard with if let Some(win) = app.get_webview_window("settings") { win.set_focus(); return Ok(()); } before building. Use WebviewUrl::App with your route. The label "settings" is what makes the guard work.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.