Using Browser Extensions in Tauri v2

Nazar Antoniuk

Recently, I found out that not so long ago Tauri introduced a feature to enable and install browser extensions in WebView2. This feature doesn't have a guide yet, so I decided to write one myself. I hope you will find it useful.


Notes to consider:

  • This is a Windows-only feature because only WebView2 supports browser extensions and WebKit (which is used on Mac and Linux) does not.
  • Only Chromium-compatible extensions can be used because WebView2 is based on Chromium.

Prerequsites

Open your project or create a new one following the Tauri guide. For this guide, I created a new project using Tauri CLI.

You can find a complete example in this repo: https://github.com/niusia-ua/tauri-extensions-example.

Enabling Extensions

  1. Open the Tauri config and remove the window configuration from it.

    # src-tauri/tauri.conf.json
    {
      ...
      "app": {
    -   "windows": [
    -     {
    -       "title": "Tauri Browser Extensions Example",
    -       "width": 800,
    -       "height": 600
    -     }
    -   ]
      },
      "security": { "csp": null }
      ...
    }

    We can't configure the window properly in the Tauri config to use extensions, so we need to manually create the window during the application setup.

  2. Create an extensions folder somewhere in the application repository. I created this folder in the src-tauri/ folder.

  3. Get the build of the extension that you want to use and place it in the extensions folder under a specific subfolder (it can have any name).

    For example, you can install the extension in Google Chrome and find its sources in the C:\Users\{user}\AppData\Local\Google\Chrome\User Data\Default\Extensions\{extension_id}\{extension_version}. To find out the extension ID go to the chrome://extensions page and enable the Developer Mode. Then, you will see the ID on the extension card.

    In my case, I will use the Vue.js DevTools extensions, so I placed the build under src-tauri/extensions/vuejs-devtools.

  4. Now, open the file where you are building the application. In my case, this is a src-tauri/src/lib.rs.

    Edit it to look like this:

    // src-tauri/src/lib.rs
    #[cfg_attr(mobile, tauri::mobile_entry_point)]
    pub fn run() {
      tauri::Builder::default()
        // We will do all the work in the setup hook.
        .setup(|app| {
          // Start with creating the webview window builder instance.
          #[allow(unused_mut)]
          let mut webview_window_builder = tauri::WebviewWindowBuilder::new(app, "main", tauri::WebviewUrl::default())
            // You can simply hardcode the window title, but it is recommended to use one from the Tauri config.
            .title(app.package_info().name.clone())
            .inner_size(800.0, 600.0);
    
          // Next, define a code block that will only be executed for the debug Windows builds.
          #[cfg(all(debug_assertions, target_os = "windows"))]
          {
            webview_window_builder = webview_window_builder
              // Enable browser extensions.
              .browser_extensions_enabled(true)
              // Specify the path from the WebView2 will load them.
              .extensions_path(
                // Load extensions from the `src-tauri/extensions/`.
                std::env::current_dir()?.join("extensions")
              );
          }
    
          // Finally, build the webview window so the Tauri can use it.
          let webview_window = webview_window_builder.build()?;
    
          // Optionally, you can immediately open the devtools.
          #[cfg(debug_assertions)]
          webview_window.open_devtools();
    
          Ok(())
        })
        .invoke_handler(tauri::generate_handler![greet])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
    }

When you start the application, you will see the devtools window open and the Vue.js icon in the toolbar.

DevTools Screenshot

Success!

Further Improvements

After we are successful in running a local copy of the extension in WebView2, let's consider what we can improve.

Using Extensions in Production

In the example above, we use extensions only during development. However, it is possible to use them also in production.

To do so you should somehow ship the extension build to the end user. You can do it in many ways, but the easiest one is to use Tauri resources.

Loading Extensions From the User's Chrome Profile

In the example above, we worked with a local copy of the extension build. Instead, you can access the user's Chrome profile and load their extensions from there.