docs: fix custom protocol association documentation (#4825)

* docs: fix custom protocol association documentation

The documentation was incorrectly referencing `wails.json` with JSON format
when the actual configuration file is `build/config.yml` using YAML format.

Changes:
- Update config file reference from `wails.json` to `build/config.yml`
- Change format from JSON to YAML in code examples
- Fix structure: `protocols` is at root level, not nested under `info`
- Correct template variable references from `{{.Info.Protocols}}` to `{{.Protocols}}`
- Update Info.plist example to show actual generated format (`wails.com.scheme`)
- Add note about running `wails3 task common:update:build-assets` after changes
- Clean up redundant file path references in platform-specific sections

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: consolidate custom protocol docs and add Universal Links

- Remove duplicate custom-protocol-association.mdx
- Add Universal Links section to macOS tab
- Add Web-to-App Linking section to Windows tab
- Keep the more comprehensive distribution/custom-protocols.mdx

Addresses review comment about duplicate documentation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(windows): add custom protocol support to MSIX packaging

- Add uap3 namespace and protocol extension to MSIX template
- Protocols defined in build/config.yml are now automatically
  registered when building MSIX packages
- Update docs with MSIX section and clarify Web-to-App linking
  requires manual manifest configuration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Lea Anthony 2025-12-27 09:52:26 +11:00 committed by GitHub
commit ab33eb594e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 84 additions and 218 deletions

View file

@ -1,216 +0,0 @@
---
title: Custom Protocol Schemes (Deep Linking)
description: Guide to implementing custom URL schemes for deep linking in Wails applications across macOS, Windows, and Linux.
---
import { Aside } from '@astrojs/starlight/components';
# Custom Protocol Schemes (Deep Linking)
Custom protocol schemes (also known as custom URL schemes or deep linking) allow your Wails application to be launched or brought to the foreground by clicking a URL with a scheme you define (e.g., `myapp://some/data`). This is useful for various purposes, such as:
- OAuth authentication flows.
- Inter-application communication.
- Launching your app with a specific context or to perform a particular action.
Wails provides a unified way to handle these custom URL invocations across macOS, Windows, and Linux through the `events.Common.ApplicationLaunchedWithUrl` event.
## Defining Your Protocols
First, you need to define the custom protocol schemes your application will use. This is done in your `wails.json` project configuration file. Wails reads this file during the build process (`wails build`) to configure the necessary platform-specific assets like `Info.plist` for macOS, NSIS installer scripts for Windows, and `.desktop` files for Linux.
**Example: `wails.json`**
```json title="wails.json"
{
"name": "My App",
"description": "An amazing Wails app!",
"info": {
"companyName": "My Company",
"productName": "My Product",
// ... other info fields ...
"protocols": [
{
"scheme": "myapp",
"description": "My Application Custom Protocol"
},
{
"scheme": "anotherprotocol",
"description": "Another protocol for specific actions"
}
]
}
// ... other wails.json fields ...
}
```
This `info.protocols` array is what Wails uses to generate the necessary entries in platform-specific files. For example, in template files, you might access this via a path like `{{.Info.Protocols}}`.
<Aside type="note">
While `application.Options` in your `main.go` is used for runtime application settings, the definition of custom protocols for build-time asset generation (like `Info.plist`, NSIS scripts, `.desktop` files) should be managed in `wails.json`.
</Aside>
## Handling the Event in Your Application
When your application is launched or activated via a custom URL, Wails emits an `events.Common.ApplicationLaunchedWithUrl` event. You can listen for this event and retrieve the URL that triggered the launch.
```go title="main.go"
import (
"log"
"github.com/wailsapp/wails/v3/pkg/application"
"github.com/wailsapp/wails/v3/pkg/events"
)
func main() {
app := application.New(application.Options{
Name: "My App", // Ensure this matches relevant info from wails.json if needed
Description: "An amazing Wails app!",
// ... other runtime options ...
})
app.Event.OnApplicationEvent(events.Common.ApplicationLaunchedWithUrl, func(e *application.ApplicationEvent) {
launchedURL := e.Context().URL() // Retrieve the URL from the event context
log.Printf("Application launched with URL: %s", launchedURL)
// TODO: Process the URL (e.g., navigate, perform action, etc.)
// Example: app.Event.Emit("frontend:ShowURL", launchedURL)
})
// ... rest of your main function ...
err := app.Run()
if err != nil {
log.Fatal(err)
}
}
```
<Aside type="note">
The `e.Context().URL()` method returns the full URL string that was used to launch the application (e.g., `myapp://some/data?param=value`).
</Aside>
## Platform-Specific Setup and Behavior
While Wails aims for a unified event, the underlying mechanism for custom protocol registration and URL delivery varies by operating system.
### macOS
- **Setup:** Wails automatically configures your application's `Info.plist` file during the build process. It adds `CFBundleURLTypes` entries based on the `info.protocols` defined in your `wails.json` file.
```xml title="Info.plist (excerpt generated by Wails)"
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>My Application Custom Protocol</string> <!-- From Protocol.Description in wails.json -->
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string> <!-- From Protocol.Scheme in wails.json -->
</array>
</dict>
<!-- ... other protocols ... -->
</array>
```
- **How it Works:** When a URL like `myapp://` is opened, macOS uses LaunchServices to find the application registered for that scheme and sends it an Apple Event (`kAEGetURL`). Wails intercepts this event and translates it into the common `events.Common.ApplicationLaunchedWithUrl` Wails event, providing the URL via `e.Context().URL()`.
#### Universal Links
In addition to custom protocol schemes, macOS also supports **Universal Links**, which allow your app to be launched by regular HTTPS links (e.g., `https://myawesomeapp.com/path`). Universal Links provide a seamless user experience between your web and desktop app.
<Aside type="caution">
Universal Links require your macOS app to be **code-signed** with a valid Apple Developer certificate and provisioning profile. Unsigned or ad-hoc signed builds will not be able to open Universal Links. Ensure your app is properly signed before testing.
</Aside>
To enable Universal Links, follow the [Apple guide on supporting Universal Links in your app](https://developer.apple.com/documentation/xcode/supporting-universal-links-in-your-app). You'll need to:
1. **Add entitlements** in your `entitlements.plist`:
```xml title="entitlements.plist"
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:myawesomeapp.com</string>
</array>
```
2. **Add NSUserActivityTypes to Info.plist**:
```xml title="Info.plist"
<key>NSUserActivityTypes</key>
<array>
<string>NSUserActivityTypeBrowsingWeb</string>
</array>
```
3. **Configure `apple-app-site-association` on your website:** Host an `apple-app-site-association` file at `https://myawesomeapp.com/.well-known/apple-app-site-association`.
When a Universal Link triggers your app, you'll receive the same `events.Common.ApplicationLaunchedWithUrl` event, making the handling code identical to custom protocol schemes.
### Windows
- **Setup:** Custom protocol schemes on Windows are registered in the Windows Registry. Wails facilitates this through its NSIS installer template.
- When you build your application with the `-nsis` flag, Wails uses the `v3/internal/commands/updatable_build_assets/windows/nsis/wails_tools.nsh.tmpl` file.
- This template contains macros like `CUSTOM_PROTOCOL_ASSOCIATE` and `wails.associateCustomProtocols` which use the `info.protocols` from your `wails.json` (passed as `{{.Info.Protocols}}` to the template) to create the necessary registry entries during installation.
```nsis title="wails_tools.nsh.tmpl (excerpt)"
!macro wails.associateCustomProtocols
; Create custom protocols associations
{{range .Info.Protocols}}
!insertmacro CUSTOM_PROTOCOL_ASSOCIATE "{{.Scheme}}" "{{.Description}}" "$INSTDIR\${PRODUCT_EXECUTABLE},0" "$INSTDIR\${PRODUCT_EXECUTABLE} $\"%1$\""
{{end}}
!macroend
```
- **How it Works:** The installer registers your application executable to be called with the URL as a command-line argument (`%1`). For example, `your_app.exe "myapp://some/data"`.
- The Wails runtime for Windows (`v3/pkg/application/application_windows.go`) has been updated to check `os.Args` upon startup. If it detects an argument that looks like a URL (e.g., `os.Args[1]` contains `"://"`), it now emits the `events.Common.ApplicationLaunchedWithUrl` event with this URL.
<Aside type="caution">
For Windows, custom protocol schemes are typically only registered when your application is installed via an installer (like the one generated by Wails with NSIS). Running the bare executable might not have the schemes registered system-wide.
</Aside>
#### Universal Links (Web-to-App Linking)
Windows supports **Web-to-App linking**, which works similarly to Universal Links on macOS. When deploying your application as an MSIX package, you can enable HTTPS links to launch your app directly.
To enable Web-to-App linking, follow the [Microsoft guide on web-to-app linking](https://learn.microsoft.com/en-us/windows/apps/develop/launch/web-to-app-linking). You'll need to:
1. **Add App URI Handler in your MSIX manifest**:
```xml title="AppPackage.appxmanifest (excerpt)"
<uap3:Extension Category="windows.appUriHandler">
<uap3:AppUriHandler>
<uap3:Host Name="myawesomeapp.com"/>
</uap3:AppUriHandler>
</uap3:Extension>
```
2. **Configure `windows-app-web-link` on your website:** Host a `windows-app-web-link` file at `https://my.app.org/.well-known/windows-app-web-link`. This file should contain your app's package information and the paths it handles.
When a Web-to-App link launches your application, you'll receive the same `events.Common.ApplicationLaunchedWithUrl` event as with custom protocol schemes.
### Linux
- **Setup:** On Linux, custom protocol handling is typically managed via `.desktop` files and the MIME type system.
- Wails uses a `.desktop` file template (e.g., `v3/internal/commands/updatable_build_assets/linux/desktop.tmpl`) which is populated during the build using information from `wails.json`.
```desktop title="desktop.tmpl (excerpt)"
[Desktop Entry]
Name={{.ProductName}}
Exec=/usr/local/bin/{{.BinaryName}} %u
MimeType={{range $index, $protocol := .Info.Protocols}}x-scheme-handler/{{$protocol.Scheme}};{{end}}
```
The `Exec` line uses `%u` which gets replaced by the URL. The `MimeType` line registers your application as a handler for `x-scheme-handler/your-scheme` for each protocol defined in `wails.json` (via `{{.Info.Protocols}}`).
- When packaging for Linux (e.g., using `nfpm`), this `.desktop` file is installed to `/usr/share/applications/`.
- A `postinstall.sh` script (e.g., `v3/internal/commands/build_assets/linux/nfpm/scripts/postinstall.sh`) is used to update the system's application and MIME databases:
```sh title="postinstall.sh (excerpt)"
#!/bin/sh
update-desktop-database -q /usr/share/applications
update-mime-database -n /usr/share/mime
```
- **How it Works:** When a URL like `myapp://` is opened, the desktop environment uses the MIME database to find the associated `.desktop` file and executes the command specified in its `Exec` line, substituting `%u` with the URL. Your application receives this URL as a command-line argument.
- The Wails runtime for Linux (`v3/pkg/application/application_linux.go`) checks `os.Args` on startup. If it detects an argument that looks like a URL, it emits the `events.Common.ApplicationLaunchedWithUrl` event.
## Testing Your Custom Protocols
- **macOS:** Open Terminal and type `open "your-scheme://your/data"`.
- **Linux:** Open a terminal and type `xdg-open "your-scheme://your/data"` (requires `xdg-utils` to be installed and the app to be properly packaged and registered).
- **Windows:** After installation via NSIS:
- You can try running `start your-scheme://your/data` from Command Prompt or PowerShell.
- Create a simple HTML file with a link `<a href="your-scheme://your/data">Test Link</a>` and open it in a browser.
<Aside type="tip">
Always ensure your application is properly built and installed (especially for Windows and Linux) for the system to recognize the custom protocol schemes.
</Aside>
By following this guide, you can effectively use custom protocol schemes to enhance your Wails application's interactivity and integration with other applications or web services.

View file

@ -5,7 +5,7 @@ sidebar:
order: 3
---
import { Tabs, TabItem } from '@astrojs/starlight/components';
import { Tabs, TabItem, Aside } from '@astrojs/starlight/components';
Custom URL protocols (also called URL schemes) allow your application to be launched when users click links with your custom protocol, such as `myapp://action` or `myapp://open/document`.
@ -159,6 +159,47 @@ Start-Process "myapp://test/action"
start myapp://test/action
```
### Windows MSIX Package
Custom protocols are also automatically registered when using MSIX packaging.
#### Automatic Registration
When you build your application with MSIX, the manifest automatically includes protocol registrations from your `build/config.yml` protocols configuration.
The generated manifest includes:
```xml
<uap:Extension Category="windows.protocol">
<uap:Protocol Name="myapp">
<uap:DisplayName>My Application Protocol</uap:DisplayName>
</uap:Protocol>
</uap:Extension>
```
#### Universal Links (Web-to-App Linking)
Windows supports **Web-to-App linking**, which works similarly to Universal Links on macOS. When deploying your application as an MSIX package, you can enable HTTPS links to launch your app directly.
<Aside type="note">
Web-to-App linking requires manual manifest configuration. Custom protocol schemes are automatically configured from `build/config.yml`, but associated domains must be added manually to your MSIX manifest.
</Aside>
To enable Web-to-App linking, follow the [Microsoft guide on web-to-app linking](https://learn.microsoft.com/en-us/windows/apps/develop/launch/web-to-app-linking). You'll need to:
1. **Manually add App URI Handler to your MSIX manifest** (`build/windows/msix/app_manifest.xml`):
```xml
<uap3:Extension Category="windows.appUriHandler">
<uap3:AppUriHandler>
<uap3:Host Name="myawesomeapp.com"/>
</uap3:AppUriHandler>
</uap3:Extension>
```
2. **Configure `windows-app-web-link` on your website:** Host a `windows-app-web-link` file at `https://myawesomeapp.com/.well-known/windows-app-web-link`. This file should contain your app's package information and the paths it handles.
When a Web-to-App link launches your application, you'll receive the same `ApplicationOpenedWithURL` event as with custom protocol schemes.
</TabItem>
<TabItem label="macOS" icon="apple">
@ -199,6 +240,36 @@ open "myapp://test/action"
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -dump | grep myapp
```
#### Universal Links
In addition to custom protocol schemes, macOS also supports **Universal Links**, which allow your app to be launched by regular HTTPS links (e.g., `https://myawesomeapp.com/path`). Universal Links provide a seamless user experience between your web and desktop app.
<Aside type="caution">
Universal Links require your macOS app to be **code-signed** with a valid Apple Developer certificate and provisioning profile. Unsigned or ad-hoc signed builds will not be able to open Universal Links. Ensure your app is properly signed before testing.
</Aside>
To enable Universal Links, follow the [Apple guide on supporting Universal Links in your app](https://developer.apple.com/documentation/xcode/supporting-universal-links-in-your-app). You'll need to:
1. **Add entitlements** in your `entitlements.plist`:
```xml
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:myawesomeapp.com</string>
</array>
```
2. **Add NSUserActivityTypes to Info.plist**:
```xml
<key>NSUserActivityTypes</key>
<array>
<string>NSUserActivityTypeBrowsingWeb</string>
</array>
```
3. **Configure `apple-app-site-association` on your website:** Host an `apple-app-site-association` file at `https://myawesomeapp.com/.well-known/apple-app-site-association`.
When a Universal Link triggers your app, you'll receive the same `ApplicationOpenedWithURL` event, making the handling code identical to custom protocol schemes.
</TabItem>
<TabItem label="Linux" icon="linux">

View file

@ -17,12 +17,14 @@ After processing, the content will be moved to the main changelog and this file
## Added
<!-- New features, capabilities, or enhancements -->
- Add custom protocol support to MSIX packaging by @leaanthony
## Changed
<!-- Changes in existing functionality -->
## Fixed
<!-- Bug fixes -->
- Consolidate custom protocol documentation and add Universal Links sections by @leaanthony
## Deprecated
<!-- Soon-to-be removed features -->

View file

@ -2,8 +2,10 @@
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10">
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
IgnorableNamespaces="uap3">
<Identity
Name="{{.ProductIdentifier}}"
@ -54,6 +56,13 @@
</uap:FileTypeAssociation>
</uap:Extension>
{{end}}
{{range .Protocols}}
<uap:Extension Category="windows.protocol">
<uap:Protocol Name="{{.Scheme}}">
<uap:DisplayName>{{.Description}}</uap:DisplayName>
</uap:Protocol>
</uap:Extension>
{{end}}
</Extensions>
</Application>
</Applications>