# How to Control Webview Navigation with Tauri Commands: Reload, Back, and Forward

> Learn to control Tauri webview navigation with Rust commands. Execute JavaScript to reload, go back, and forward within your application. Enhance user experience with seamless navigation.

- Repository: [lencx/ChatGPT](https://github.com/lencx/ChatGPT)
- Tags: how-to-guide
- Published: 2026-03-06

---

**You can control webview navigation in Tauri by registering Rust commands that use `eval()` to execute JavaScript navigation APIs like `window.location.reload()` and `window.history.back()` inside the webview.**

The lencx/ChatGPT desktop application demonstrates a robust pattern for controlling embedded webview navigation using Tauri commands. By exposing Rust functions that evaluate JavaScript directly in the webview context, the application enables seamless reload, back, and forward functionality from the native UI. This architecture bridges the React frontend and the underlying WebKit webview through Tauri's command system.

## Architecture of Webview Navigation Commands

The navigation system relies on three coordinated components: command registration in the Rust entry point, implementation in a dedicated commands module, and invocation from the frontend via Tauri's JavaScript API.

### Command Registration in main.rs

In [`src-tauri/src/main.rs`](https://github.com/lencx/ChatGPT/blob/main/src-tauri/src/main.rs), the Tauri builder registers the navigation handlers using `generate_handler!`. This exposes the Rust functions to the frontend runtime:

```rust
tauri::Builder::default()
    .plugin(tauri_plugin_os::init())
    .plugin(tauri_plugin_shell::init())
    .plugin(tauri_plugin_dialog::init())
    .invoke_handler(tauri::generate_handler![
        cmd::view_reload,
        cmd::view_go_forward,
        cmd::view_go_back,
        // … other commands
    ])
    .run(tauri::generate_context!())
    .expect("error while running lencx/ChatGPT application");

```

### Command Implementation in cmd.rs

The actual navigation logic resides in [`src-tauri/src/core/cmd.rs`](https://github.com/lencx/ChatGPT/blob/main/src-tauri/src/core/cmd.rs). Each command obtains the **AppHandle**, retrieves the window labeled `"core"`, fetches the webview named `"main"`, and executes the corresponding JavaScript navigation method via `eval()`:

**Reload functionality** uses `window.location.reload()`:

```rust
#[command]
pub fn view_reload(app: AppHandle) {
    app.get_window("core")
        .unwrap()
        .get_webview("main")
        .unwrap()
        .eval("window.location.reload()")
        .unwrap();
}

```

**Forward navigation** uses `window.history.forward()`:

```rust
#[command]
pub fn view_go_forward(app: AppHandle) {
    app.get_window("core")
        .unwrap()
        .get_webview("main")
        .unwrap()
        .eval("window.history.forward()")
        .unwrap();
}

```

**Back navigation** uses `window.history.back()`:

```rust
#[command]
pub fn view_go_back(app: AppHandle) {
    app.get_window("core")
        .unwrap()
        .get_webview("main")
        .unwrap()
        .eval("window.history.back()")
        .unwrap();
}

```

### Frontend Invocation via Tauri API

The React frontend invokes these commands using `@tauri-apps/api/core`. In [`src/view/Titlebar.tsx`](https://github.com/lencx/ChatGPT/blob/main/src/view/Titlebar.tsx), button click handlers call `invoke()` with the command names:

```tsx
import { invoke } from '@tauri-apps/api/core';

const handleRefresh = () => {
  invoke('view_reload');
};

const handleGoForward = () => {
  invoke('view_go_forward');
};

const handleGoBack = () => {
  invoke('view_go_back');
};

```

These handlers are bound to the title bar navigation icons, creating a seamless native navigation experience.

## Implementation Guide for Custom Navigation

### Accessing Webviews by Label

The lencx/ChatGPT implementation targets specific window and webview labels. The `get_window("core")` call retrieves the main application window, while `get_webview("main")` targets the primary content webview. Ensure your [`tauri.conf.json`](https://github.com/lencx/ChatGPT/blob/main/tauri.conf.json) defines these labels, or modify the code to match your configuration.

### Error Handling Considerations

The example code uses `.unwrap()` for brevity. In production applications, implement proper error handling to manage cases where the window or webview might not be available:

```rust
#[command]
pub fn view_reload(app: AppHandle) -> Result<(), String> {
    let window = app.get_window("core").ok_or("Window not found")?;
    let webview = window.get_webview("main").ok_or("Webview not found")?;
    webview.eval("window.location.reload()").map_err(|e| e.to_string())?;
    Ok(())
}

```

### Extending Navigation Capabilities

You can extend this pattern to support additional navigation actions by modifying the JavaScript string passed to `eval()`. For example, to navigate to a specific URL:

```rust
#[command]
pub fn view_navigate(app: AppHandle, url: String) {
    app.get_window("core")
        .unwrap()
        .get_webview("main")
        .unwrap()
        .eval(&format!("window.location.href = '{}'", url))
        .unwrap();
}

```

## Summary

- **Command registration** occurs in [`src-tauri/src/main.rs`](https://github.com/lencx/ChatGPT/blob/main/src-tauri/src/main.rs) using `tauri::generate_handler!` to expose Rust functions to the frontend.
- **Navigation implementation** in [`src-tauri/src/core/cmd.rs`](https://github.com/lencx/ChatGPT/blob/main/src-tauri/src/core/cmd.rs) uses `app.get_window("core").get_webview("main").eval()` to execute JavaScript navigation APIs.
- **JavaScript evaluation** enables access to standard browser APIs including `window.location.reload()`, `window.history.back()`, and `window.history.forward()`.
- **Frontend integration** uses `invoke()` from `@tauri-apps/api/core` to trigger navigation from React components as demonstrated in [`src/view/Titlebar.tsx`](https://github.com/lencx/ChatGPT/blob/main/src/view/Titlebar.tsx).
- **Window and webview labels** must match between your Rust code and Tauri configuration (the ChatGPT app uses `"core"` for the window and `"main"` for the webview).

## Frequently Asked Questions

### How do I reload a Tauri webview from Rust?

Register a command that retrieves your webview instance and call `eval()` with `window.location.reload()`. In the lencx/ChatGPT codebase, the `view_reload` function in [`src-tauri/src/core/cmd.rs`](https://github.com/lencx/ChatGPT/blob/main/src-tauri/src/core/cmd.rs) demonstrates this pattern by targeting the "main" webview within the "core" window.

### Can I navigate back and forward in a Tauri webview using commands?

Yes. Expose commands that evaluate `window.history.back()` and `window.history.forward()` in the webview context. The ChatGPT application implements `view_go_back` and `view_go_forward` commands in [`src-tauri/src/core/cmd.rs`](https://github.com/lencx/ChatGPT/blob/main/src-tauri/src/core/cmd.rs), which are bound to the title bar navigation buttons in the React frontend.

### What is the difference between using Tauri commands versus frontend JavaScript for navigation?

Tauri commands execute in the Rust backend with access to the full Tauri API, allowing navigation triggers from native menus, keyboard shortcuts, or system events. Frontend JavaScript navigation only works when the webview content is focused and executable. The command pattern also enables navigation when the webview might not have JavaScript execution context available or when triggered from the native application menu.

### How do I target a specific webview when multiple exist in a Tauri window?

Use the `get_webview()` method with the specific label defined in your configuration. The lencx/ChatGPT application uses `get_webview("main")` to target the primary content webview, distinguishing it from any auxiliary webviews that might exist in the "core" window. Always ensure the webview label matches exactly between your Rust code and [`tauri.conf.json`](https://github.com/lencx/ChatGPT/blob/main/tauri.conf.json).