起動時にウィンドウを表示せず、システムトレイ常駐型のアプリケーションとして動作させる方法を解説します。
Tauri の JavaScript API を利用するためには、WebView(ウィンドウ)が存在している必要があります。そのため、「ウィンドウを表示しない(Hidden)」状態で起動し、JavaScript でトレイアイコンを制御する方法が最も簡単で柔軟です。
前提条件
プラグインの導入
アプリ終了 (exit) コマンドを使用するため、process プラグインを導入します。
npm run tauri add process
src-tauri/src/lib.rs:
.plugin(tauri_plugin_process::init()) を追加します。process プラグインをインストールすると、自動的に挿入されるはずですので、確認してください。
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_process::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
Cargo.toml の設定
Tauri v2 ではトレイ機能は Core (本体) に統合されているため、追加のプラグイン(tauri-plugin-tray など)のインストールは不要です。
ただし、src-tauri/Cargo.toml で tray-icon 機能を有効にする必要があります。
[dependencies]
tauri = { version = "2", features = ["tray-icon", "image-png"] }
Permissions (権限) の設定
src-tauri/capabilities/default.json に以下を追加します。
{
"permissions": [
...,
"core:window:allow-hide",
"core:window:allow-is-visible",
"core:window:allow-set-focus",
"core:window:allow-show",
"core:tray:default",
"core:menu:default",
"core:app:allow-default-window-icon",
"process:default"
]
}
設定
tauri.conf.json で非表示設定
src-tauri/tauri.conf.json の app.windows 設定で、メインウィンドウの visible プロパティを false に設定します。
{
"app": {
"windows": [
{
"title": "My Hidden App",
"label": "main",
"visible": false
}
]
}
}
1. フロントエンドで実装する (TypeScript)
アプリ起動時(JavaScript ロード時)にトレイアイコンを作成します。
import { TrayIcon } from '@tauri-apps/api/tray';
import { Menu } from '@tauri-apps/api/menu';
import { exit } from '@tauri-apps/plugin-process';
import { getCurrentWindow } from '@tauri-apps/api/window';
import { defaultWindowIcon } from '@tauri-apps/api/app';
async function initTray() {
const icon = await defaultWindowIcon();
if (!icon) return;
// メニュー作成
const menu = await Menu.new({
items: [
{
text: 'ダッシュボードを表示',
action: async () => {
const win = getCurrentWindow();
await win.show();
await win.setFocus();
}
},
{ item: 'Separator' },
{
text: '終了',
action: async () => {
await exit(0);
}
}
]
});
// トレイ作成
await TrayIcon.new({
icon: icon,
tooltip: '常駐アプリ実行中',
menu: menu,
action: async (e) => {
if (e.type === 'Click' && e.button === 'Left') {
const win = getCurrentWindow();
const isVisible = await win.isVisible();
if (isVisible) {
await win.hide();
} else {
await win.show();
await win.setFocus();
}
}
}
});
console.log('Tray initialized');
}
initTray();
2. バックエンドで実装する (Rustのみ)
WebView を使用せず、メモリ使用量を極限まで抑えたい場合は、tauri.conf.json の windows を空([])にし、Rustコードのみでトレイを作成します。
use tauri::tray::TrayIconBuilder;
use tauri::menu::{MenuBuilder, MenuItem};
pub fn run() {
tauri::Builder::default()
.setup(|app| {
// トレイメニュー
let quit_i = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>)?;
let menu = MenuBuilder::new(app)
.item(&quit_i)
.build()?;
let _tray = TrayIconBuilder::with_id("tray")
.icon(app.default_window_icon().unwrap().clone())
.menu(&menu)
.on_menu_event(|app, event| {
if event.id() == "quit" {
app.exit(0);
}
})
.build(app)?;
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
補足
* JavaScript API の使用: バックエンドのみの実装(WebViewなし)では、JavaScript API は一切使用できません。
* イベントループ: Rust コードの run メソッドがイベントループを開始するため、ウィンドウがなくてもアプリは終了せず常駐し続けます(tauri-plugin-process 等で明示的に終了しない限り)。