Native Features: Menus, Trays, and Dialogs
Native Features: Menus, Trays, and Dialogs
Section titled “Native Features: Menus, Trays, and Dialogs”One of the main reasons to use Tauri over a standard web app is the ability to integrate deeply with the Operating System. In this chapter, we will implement features that give your app that “native feel”: Application Menus, System Trays, and Native File Dialogs.
Application Menu
Section titled “Application Menu”The Application Menu appears at the top of the screen on macOS or at the top of the window on Windows and Linux. It provides standard actions like “File,” “Edit,” and “View.”
In Tauri v2, you typically construct menus in Rust within your lib.rs file. You can create a default menu or build a custom one item by item.
use tauri::menu::{Menu, MenuItem};
pub fn run() { tauri::Builder::default() .setup(|app| { // Create a custom menu let file_menu = Menu::new(app)?; file_menu.append(&MenuItem::with_id(app, "quit", "Quit", true, None::<&str>)?)?;
app.set_menu(file_menu)?; Ok(()) }) .run(tauri::generate_context!()) .expect("error while running tauri application");}System Tray
Section titled “System Tray”The System Tray (or Notification Area) allows your app to persist in the background even when the main window is closed. This is perfect for music players, chat apps, or utility tools.
To add a tray, you configure it in Rust using TrayIconBuilder. You can attach a menu to it, allowing users to right-click the icon and select options like “Show” or “Exit.”
use tauri::tray::TrayIconBuilder;
// Inside your builder chain.setup(|app| { TrayIconBuilder::new() .icon(app.default_window_icon().unwrap().clone()) .tooltip("My Tauri App") .on_menu_event(|app, event| { // Handle click events here }) .build(app)?; Ok(())})Native File Dialogs
Section titled “Native File Dialogs”Web browsers use <input type="file">, which is functional but limited. Tauri allows you to open the OS’s native file pickers for opening and saving files. This provides a familiar experience for users and allows access to the file path, not just the file buffer.
We use the official dialog plugin for this. First, ensure you have installed the plugin (@tauri-apps/plugin-dialog) and registered it in Rust.
import { open, save } from '@tauri-apps/plugin-dialog';
// Open a file selection dialogconst selected = await open({ multiple: false, filters: [{ name: 'Images', extensions: ['png', 'jpeg'] }]});
// Save a file dialogconst filePath = await save({ filters: [{ name: 'Text', extensions: ['txt'] }]});These native integrations bridge the gap between a web page and a true desktop application.