V3 Deep-link (Port of v2 feature) - #4289
Conversation
WalkthroughThis change introduces comprehensive support for custom protocol schemes (deep linking) in Wails applications across macOS, Windows, and Linux. It includes new documentation, example projects, configuration files, build scripts, and runtime logic. The update adds event types, context handling, and platform-specific implementations to enable applications to register and respond to custom URL schemes, emitting events to the frontend when launched via a registered protocol. Changes
Sequence Diagram(s)sequenceDiagram
participant OS as Operating System
participant App as Wails Application
participant Backend as Go Backend
participant Frontend as JS Frontend
OS->>App: Launch via custom URL (e.g., myapp://...)
App->>Backend: Emit ApplicationLaunchedWithUrl event with URL context
Backend->>Frontend: Emit frontend event (e.g., "ShowURL") with URL data
Frontend->>Frontend: Display or process received URL
Poem
📜 Recent review detailsConfiguration used: .coderabbit.yaml 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
|
There was a problem hiding this comment.
Actionable comments posted: 13
🔭 Outside diff range comments (4)
v3/examples/custom-protocol-example/build/linux/nfpm/scripts/preremove.sh (1)
1-2: 🛠️ Refactor suggestionScript is empty but should include cleanup logic for protocol handlers
This preremove script is executed before package removal on Linux systems. While the shebang is present, the script lacks any actual commands to clean up the custom protocol associations that were set up during installation.
Consider adding commands to unregister the protocol handlers from the system. Here's a suggested implementation:
#!/bin/bash + +# Remove desktop file associations +update-desktop-database -q + +# Clean up MIME type associations if necessary +update-mime-database -q /usr/share/mimev3/examples/custom-protocol-example/build/linux/nfpm/scripts/postinstall.sh (1)
1-2: 🛠️ Refactor suggestionScript is empty but should update desktop and MIME databases
This postinstall script is intended to run after package installation to register the application and its custom protocol handlers on Linux systems. However, it's missing the necessary commands to update the system databases.
Add commands to update desktop and MIME databases to ensure proper protocol registration:
#!/bin/bash + +# Update desktop file associations +update-desktop-database -q + +# Update MIME type database +update-mime-database -q /usr/share/mimev3/examples/custom-protocol-example/README.md (1)
1-60: 🛠️ Refactor suggestionAdd information about the custom protocol feature
While the README provides good general guidance for Wails3 projects, it doesn't mention the custom protocol handling feature that this example specifically demonstrates. Consider adding a section explaining:
- What custom protocols are
- How they're implemented in this example
- How to test the custom protocol functionality
Add a new section after "Getting Started" or "Project Structure":
## Custom Protocol Feature This example demonstrates how to implement and use custom URL protocols (deep linking) in a Wails3 application. With this feature, your application can be launched from custom URLs like `wailsexample://some/path`. ### How It Works 1. The custom protocol is defined in `wails.json` under the `protocols` section: ```json "protocols": [ { "scheme": "wailsexample", "description": "Wails Example Protocol" } ]
The application listens for launch events via the custom protocol:
app.OnApplicationEvent(events.Common.ApplicationLaunchedWithUrl, func(e *application.ApplicationEvent) { app.EmitEvent("frontend:ShowURL", e.Context().URL()) })The frontend receives and displays the URL:
window.runtime.EventsOn("frontend:ShowURL", (url) => { document.getElementById("launch-url").textContent = url; });Testing the Custom Protocol
After building and installing the application:
- On macOS: Open Terminal and type:
open "wailsexample://test/url"- On Windows: Type
wailsexample://test/urlin the Run dialog (Win+R)- On Linux: Run
xdg-open "wailsexample://test/url"in a terminalThe application should launch and display the URL.
<details> <summary>🧰 Tools</summary> <details> <summary>🪛 LanguageTool</summary> [uncategorized] ~47-~47: Loose punctuation mark. Context: ...h your project structure: - `frontend/`: Contains your frontend code (HTML, CSS,... (UNLIKELY_OPENING_PUNCTUATION) --- [style] ~59-~59: Using many exclamation marks might seem excessive (in this case: 3 exclamation marks for a text that’s 2020 characters long) Context: ...wails3 build`. Happy coding with Wails3! If you encounter any issues or have que... (EN_EXCESSIVE_EXCLAMATION) </details> <details> <summary>🪛 markdownlint-cli2 (0.17.2)</summary> 11-11: Fenced code blocks should have a language specified null (MD040, fenced-code-language) --- 19-19: Fenced code blocks should have a language specified null (MD040, fenced-code-language) --- 33-33: Fenced code blocks should have a language specified null (MD040, fenced-code-language) </details> </details> </blockquote></details> <details> <summary>v3/pkg/application/context_application_event.go (1)</summary><blockquote> `70-100`: _🛠️ Refactor suggestion_ **Identifier shadowing hides the package-level `url` constant** Inside `URL()` you redeclare `url`: ```go url, ok := c.data[url]After this line the variable
urlshadows the constanturl, reducing clarity and increasing the chance of accidental misuse.
Rename the local variable (e.g.uorrawURL) to avoid shadowing:-func (c ApplicationEventContext) URL() string { - url, ok := c.data[url] +func (c ApplicationEventContext) URL() string { + rawURL, ok := c.data[url]
🧹 Nitpick comments (25)
v3/examples/custom-protocol-example/build/linux/nfpm/scripts/preinstall.sh (1)
1-2: Enhance script robustness & portability.Currently this stub only includes a bash shebang. Consider switching to a
#!/usr/bin/env bashshebang for portability, and add strict mode (set -euo pipefail) plus a comment describing why no preinstall actions are needed.Apply this diff:
-#!/bin/bash +#!/usr/bin/env bash +set -euo pipefail +# No preinstall steps required for the custom protocol examplev3/examples/custom-protocol-example/build/linux/nfpm/scripts/postremove.sh (1)
1-2: Make stub script portable & add strict mode.As with
preinstall.sh, consider using#!/usr/bin/env bash, enabling strict mode, and adding a placeholder comment:-#!/bin/bash +#!/usr/bin/env bash +set -euo pipefail +# No post-remove cleanup required for the custom protocol examplev3/examples/custom-protocol-example/build/windows/info.json (1)
1-15: Metadata contains placeholder valuesThe Windows build metadata is structured correctly, but contains generic placeholder values that should be customized for the actual application.
Consider updating the placeholder values to match the actual custom-protocol-example application:
{ "fixed": { "file_version": "0.0.1" }, "info": { "0000": { "ProductVersion": "0.0.1", - "CompanyName": "My Company", - "FileDescription": "A program that does X", - "LegalCopyright": "(c) 2025, My Company", - "ProductName": "My Product", - "Comments": "Some Product Comments" + "CompanyName": "Wails", + "FileDescription": "Custom Protocol Example Application", + "LegalCopyright": "(c) 2025, Wails Contributors", + "ProductName": "Custom Protocol Example", + "Comments": "Demonstrates custom protocol handling in Wails applications" } } }v3/examples/custom-protocol-example/frontend/src/counter.js (1)
1-9: Counter implementation looks good but could benefit from enhancementsThe counter implementation is clean and functional for demonstration purposes. It properly encapsulates the counter state, sets up the event listener, and updates the UI.
For a more robust implementation in a production environment, consider adding:
export function setupCounter(element) { + if (!element) return; let counter = 0 const setCounter = (count) => { counter = count element.innerHTML = `count is ${counter}` } - element.addEventListener('click', () => setCounter(counter + 1)) + const clickHandler = () => setCounter(counter + 1); + element.addEventListener('click', clickHandler) setCounter(0) + + // Return cleanup function to remove event listener if needed + return () => { + element.removeEventListener('click', clickHandler); + } }v3/examples/custom-protocol-example/frontend/index.html (1)
1-13: Basic HTML structure is appropriate for the exampleThe HTML file provides a clean, minimal structure for mounting the frontend application. It properly includes the necessary meta tags and script reference.
Consider updating the title to better reflect the purpose of this example:
<meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <title>Vite App</title> + <title>Wails Custom Protocol Example</title>v3/examples/custom-protocol-example/greetservice.go (1)
1-7: Simple service implementation looks goodThe
GreetServiceimplementation is clean, minimal, and appropriate for demonstration purposes.Consider adding GoDoc comments to document the service and method:
package main +// GreetService provides greeting functionality for the application type GreetService struct{} +// Greet returns a personalized greeting message for the given name func (g *GreetService) Greet(name string) string { return "Hello " + name + "!" }v3/internal/commands/updatable_build_assets/darwin/Info.dev.plist.tmpl (1)
54-68: Well-implemented macOS custom protocol configurationThe addition of the
CFBundleURLTypessection correctly implements macOS custom URL scheme handling according to Apple's guidelines. The conditional template logic ensures this section only appears when protocols are defined in the application configuration.Consider making the URL name format (
wails.com.{{.Scheme}}) configurable in the future to allow developers to use their own domain formats, but this implementation is solid for the initial release of the feature.For future enhancement:
- <string>wails.com.{{.Scheme}}</string> + <string>{{.URLName | default (printf "wails.com.%s" .Scheme)}}</string>This would allow developers to specify a custom URL name if desired, while maintaining the current pattern as a default.
v3/examples/custom-protocol-example/build/linux/appimage/build.sh (1)
17-31: DRY up architecture-specific download logic and pin linuxdeploy version.The
if/elseblocks are almost identical except for the URL and binary name. Consider extracting into a helper function and pinning to a known release tag instead ofcontinuousto avoid unpredictable breakage:+LINUXDEPLOY_VERSION="1.6.2" +download_linuxdeploy() { + local arch_suffix=$1 # "x86_64" or "aarch64" + local img="linuxdeploy-${arch_suffix}.AppImage" + local url="https://github.com/linuxdeploy/linuxdeploy/releases/download/${LINUXDEPLOY_VERSION}/${img}" + wget -q -4 -N "$url" && chmod +x "$img" + ./"$img" --appdir "${APP_DIR}" --output appimage +} if [[ $(uname -m) == *x86_64* ]]; then - wget -q -4 -N https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage - chmod +x linuxdeploy-x86_64.AppImage - ./linuxdeploy-x86_64.AppImage --appdir "${APP_DIR}" --output appimage + download_linuxdeploy "x86_64" else - wget -q -4 -N https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-aarch64.AppImage - chmod +x linuxdeploy-aarch64.AppImage - ./linuxdeploy-aarch64.AppImage --appdir "${APP_DIR}" --output appimage + download_linuxdeploy "aarch64" fiv3/examples/custom-protocol-example/build/linux/nfpm/nfpm.yaml (1)
12-14: Update placeholder description to be meaningful.The description
"A program that does X"is a placeholder. Consider something like:description: "Custom Protocol Example: registers and handles deep links on Linux"This improves clarity for end users browsing package metadata.
v3/internal/commands/updatable_build_assets/linux/desktop.tmpl (1)
1-15: Consider addingStartupNotifyand richer categories.For a smoother UX, you could include:
StartupNotify=true Categories=Utility;Network;This ensures launch feedback is provided and the app appears under network-related menus.
v3/examples/custom-protocol-example/build/windows/wails.exe.manifest (1)
1-15: Assembly identity contains placeholder valuesThe manifest uses generic placeholder values for assembly identity (
com.mycompany.myproduct). While this works for an example, in real applications it should be replaced with the actual application identifier.The manifest correctly implements proper DPI awareness settings with appropriate fallbacks for different Windows versions, which is important for modern Windows applications.
- <assemblyIdentity type="win32" name="com.mycompany.myproduct" version="0.0.1" processorArchitecture="*"/> + <assemblyIdentity type="win32" name="com.example.wailsexample" version="0.0.1" processorArchitecture="*"/>v3/examples/custom-protocol-example/frontend/src/main.js (1)
37-45: Consider adding error handling for malformed URLsThe
displayUrlfunction handles missing DOM elements but doesn't include parsing or validation for malformed URLs. In a production application, you might want to add validation and error handling for invalid URL formats.window.displayUrl = function(url) { const urlElement = document.getElementById('received-url'); if (urlElement) { - urlElement.textContent = url || "No URL received or an error occurred."; + try { + // Optional: validate or parse the URL if needed + if (!url) { + urlElement.textContent = "No URL received or an error occurred."; + } else { + // Display the URL, possibly with formatting or parsing + urlElement.textContent = url; + } + } catch (error) { + console.error("Error processing URL:", error); + urlElement.textContent = "Error processing URL: " + error.message; + } } else { console.error("Element with ID 'received-url' not found in displayUrl."); } }v3/pkg/application/application_darwin.go (1)
404-407: Consider adding URL validationFor robustness, consider validating the URL string before emitting the event. This could help prevent issues with malformed URLs.
func HandleCustomProtocol(urlCString *C.char) { urlString := C.GoString(urlCString) + // Optional: validate the URL + if urlString == "" { + // Log an error or warning for empty URL + return + } eventContext := newApplicationEventContext() eventContext.setURL(urlString) // Emit the standard event with the URL string as data applicationEvents <- &ApplicationEvent{ Id: uint(events.Common.ApplicationLaunchedWithUrl), ctx: eventContext, } }v3/examples/custom-protocol-example/frontend/src/style.css (2)
26-26: Simplify the font-family declarationThe font-family declaration is unnecessarily verbose since you've already defined a system font stack in the
:rootselector.- font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + font-family: inherit;
1-142: Consider organizing CSS with comments for better maintainabilityThe stylesheet lacks organizational comments to separate different sections (variables, layout, components, etc.), which could make maintenance harder as the application grows.
Consider adding section comments like:
/* ----------------------------- Variables & Root Styles ----------------------------- */ /* ----------------------------- Typography ----------------------------- */ /* ----------------------------- Layout & Containers ----------------------------- */ /* ----------------------------- Components ----------------------------- */ /* ----------------------------- Media Queries ----------------------------- */v3/examples/custom-protocol-example/README.md (1)
11-14: Add language identifiers to code blocksCode blocks should have language identifiers for proper syntax highlighting.
- ``` + ```bash wails3 dev ``` - ``` + ```bash wails3 build ``` - ``` + ```bash go run . ```Also applies to: 19-22, 33-36
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
11-11: Fenced code blocks should have a language specified
null(MD040, fenced-code-language)
v3/examples/custom-protocol-example/main.go (1)
54-54: Consider storing the window referenceThe window creation result is assigned to
_, discarding the reference. If you need to manipulate this window later, you should store the reference.- _ = app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ + mainWindow := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{v3/examples/custom-protocol-example/build/config.yml (2)
47-47: Update the documentation URL placeholderThe URL placeholder "https://v3.wails.io/noit/done/yet" appears to be a temporary value that should be updated with the actual documentation URL before release.
-# More information at: https://v3.wails.io/noit/done/yet +# More information at: https://wails.io/docs/guides/custom-protocol-association
67-67: Add newline at end of fileYAML files should end with a newline character to follow standard file formatting practices. This was flagged by static analysis.
other: - name: My Other Data +🧰 Tools
🪛 YAMLlint (1.37.1)
[error] 67-67: no new line character at the end of file
(new-line-at-end-of-file)
v3/examples/custom-protocol-example/build/Taskfile.yml (2)
41-42: Redundant build command conditionThe BUILD_COMMAND variable uses a conditional that returns the same value in both cases:
- BUILD_COMMAND: '{{if eq .PRODUCTION "true"}}build{{else}}build{{end}}' + BUILD_COMMAND: 'build'
73-79: Skipping frontend development modeSimilar to the dependency installation task, the frontend development mode is also being skipped. This seems inconsistent with having a dedicated task for it.
If the example project doesn't need a frontend development mode, consider removing this task or adding a clarifying comment about why it's included but not implemented.
v3/pkg/events/events.go (1)
470-678: Event string mappings updatedThe eventToJS map has been updated with the new event and all shifted IDs. This ensures that JavaScript event handlers will correctly receive the right event names.
One suggestion: Consider adding a test to verify that all events are properly registered in the map. This could prevent future issues when adding or removing events.
v3/examples/custom-protocol-example/build/linux/Taskfile.yml (2)
104-110: Dead variable –OUTPUTFILEis defined but never usedKeeping unused vars in a Taskfile is noise and increases maintenance overhead.
Unless another task imports this value, please remove it:- OUTPUTFILE: '{{.ROOT_DIR}}/build/linux/{{.APP_NAME}}.desktop'
73-75: Typo in task description
Creates a arch linux packager package→Creates an Arch Linux package.
Pure docs but visible intask --list.docs/src/content/docs/guides/custom-protocol-association.mdx (1)
12-15: Minor wording improvement for readability“…with a specific context or to perform a particular action.” → “…in a specific context or to perform a particular action.”
The preposition “in” matches the usual English construction.🧰 Tools
🪛 LanguageTool
[uncategorized] ~14-~14: The preposition “in” seems more likely in this position.
Context: ...ion communication. - Launching your app with a specific context or to perform a part...(AI_EN_LECTOR_REPLACEMENT_PREPOSITION)
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
⛔ Files ignored due to path filters (5)
v3/examples/custom-protocol-example/build/appicon.pngis excluded by!**/*.pngv3/examples/custom-protocol-example/build/windows/icon.icois excluded by!**/*.icov3/examples/custom-protocol-example/frontend/package-lock.jsonis excluded by!**/package-lock.jsonv3/examples/custom-protocol-example/frontend/public/vite.svgis excluded by!**/*.svgv3/examples/custom-protocol-example/frontend/src/javascript.svgis excluded by!**/*.svg
📒 Files selected for processing (48)
docs/src/content/docs/guides/custom-protocol-association.mdx(1 hunks)v3/examples/custom-protocol-example/.gitignore(1 hunks)v3/examples/custom-protocol-example/README.md(1 hunks)v3/examples/custom-protocol-example/Taskfile.yml(1 hunks)v3/examples/custom-protocol-example/build/Taskfile.yml(1 hunks)v3/examples/custom-protocol-example/build/config.yml(1 hunks)v3/examples/custom-protocol-example/build/darwin/Info.dev.plist(1 hunks)v3/examples/custom-protocol-example/build/darwin/Info.plist(1 hunks)v3/examples/custom-protocol-example/build/darwin/Taskfile.yml(1 hunks)v3/examples/custom-protocol-example/build/linux/Taskfile.yml(1 hunks)v3/examples/custom-protocol-example/build/linux/appimage/build.sh(1 hunks)v3/examples/custom-protocol-example/build/linux/nfpm/nfpm.yaml(1 hunks)v3/examples/custom-protocol-example/build/linux/nfpm/scripts/postinstall.sh(1 hunks)v3/examples/custom-protocol-example/build/linux/nfpm/scripts/postremove.sh(1 hunks)v3/examples/custom-protocol-example/build/linux/nfpm/scripts/preinstall.sh(1 hunks)v3/examples/custom-protocol-example/build/linux/nfpm/scripts/preremove.sh(1 hunks)v3/examples/custom-protocol-example/build/windows/Taskfile.yml(1 hunks)v3/examples/custom-protocol-example/build/windows/info.json(1 hunks)v3/examples/custom-protocol-example/build/windows/nsis/project.nsi(1 hunks)v3/examples/custom-protocol-example/build/windows/nsis/wails_tools.nsh(1 hunks)v3/examples/custom-protocol-example/build/windows/wails.exe.manifest(1 hunks)v3/examples/custom-protocol-example/frontend/.gitignore(1 hunks)v3/examples/custom-protocol-example/frontend/bindings/github.com/wailsapp/wails/v3/examples/custom-protocol-example/greetservice.js(1 hunks)v3/examples/custom-protocol-example/frontend/bindings/github.com/wailsapp/wails/v3/examples/custom-protocol-example/index.js(1 hunks)v3/examples/custom-protocol-example/frontend/index.html(1 hunks)v3/examples/custom-protocol-example/frontend/package.json(1 hunks)v3/examples/custom-protocol-example/frontend/src/counter.js(1 hunks)v3/examples/custom-protocol-example/frontend/src/main.js(1 hunks)v3/examples/custom-protocol-example/frontend/src/style.css(1 hunks)v3/examples/custom-protocol-example/greetservice.go(1 hunks)v3/examples/custom-protocol-example/main.go(1 hunks)v3/internal/commands/build-assets.go(5 hunks)v3/internal/commands/build_assets/linux/nfpm/scripts/postinstall.sh(1 hunks)v3/internal/commands/updatable_build_assets/darwin/Info.dev.plist.tmpl(1 hunks)v3/internal/commands/updatable_build_assets/darwin/Info.plist.tmpl(1 hunks)v3/internal/commands/updatable_build_assets/linux/desktop.tmpl(1 hunks)v3/internal/commands/updatable_build_assets/linux/nfpm/nfpm.yaml.tmpl(2 hunks)v3/internal/runtime/desktop/@wailsio/runtime/src/event_types.ts(1 hunks)v3/pkg/application/application_darwin.go(3 hunks)v3/pkg/application/application_darwin_delegate.h(1 hunks)v3/pkg/application/application_darwin_delegate.m(3 hunks)v3/pkg/application/application_linux.go(3 hunks)v3/pkg/application/application_windows.go(4 hunks)v3/pkg/application/context_application_event.go(3 hunks)v3/pkg/events/events.go(6 hunks)v3/pkg/events/events.txt(1 hunks)v3/pkg/events/events_darwin.h(1 hunks)v3/pkg/events/events_linux.h(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
v3/examples/custom-protocol-example/greetservice.go (1)
v3/examples/custom-protocol-example/frontend/bindings/github.com/wailsapp/wails/v3/examples/custom-protocol-example/greetservice.js (1)
Greet(13-15)
v3/pkg/application/application_darwin.go (3)
v3/pkg/events/events.go (2)
Mac(92-92)Common(6-6)v3/pkg/application/application_darwin_delegate.h (1)
HandleCustomProtocol(17-17)v3/pkg/application/events.go (1)
ApplicationEvent(11-16)
v3/pkg/application/application_linux.go (2)
v3/pkg/application/events.go (1)
ApplicationEvent(11-16)v3/pkg/events/events.go (1)
Common(6-6)
🪛 YAMLlint (1.37.1)
v3/examples/custom-protocol-example/build/config.yml
[error] 67-67: no new line character at the end of file
(new-line-at-end-of-file)
🪛 LanguageTool
v3/examples/custom-protocol-example/README.md
[uncategorized] ~47-~47: Loose punctuation mark.
Context: ...h your project structure: - frontend/: Contains your frontend code (HTML, CSS,...
(UNLIKELY_OPENING_PUNCTUATION)
[style] ~59-~59: Using many exclamation marks might seem excessive (in this case: 3 exclamation marks for a text that’s 2020 characters long)
Context: ...wails3 build`. Happy coding with Wails3! If you encounter any issues or have que...
(EN_EXCESSIVE_EXCLAMATION)
docs/src/content/docs/guides/custom-protocol-association.mdx
[uncategorized] ~14-~14: The preposition “in” seems more likely in this position.
Context: ...ion communication. - Launching your app with a specific context or to perform a part...
(AI_EN_LECTOR_REPLACEMENT_PREPOSITION)
🪛 markdownlint-cli2 (0.17.2)
v3/examples/custom-protocol-example/README.md
11-11: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
19-19: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
33-33: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
🔇 Additional comments (59)
v3/examples/custom-protocol-example/.gitignore (1)
1-6: Patterns appear comprehensive – approving .gitignore entries.The listed build artifacts and dependency directories align with the platforms and tooling used in this example. No obvious omissions.
v3/examples/custom-protocol-example/frontend/.gitignore (1)
1-24: .gitignore looks solid.This frontend ignore covers common logs, node_modules, dist outputs, and IDE files. No missing patterns detected.
v3/pkg/events/events.txt (1)
2-4: New event placement is correct.
common:ApplicationLaunchedWithUrlis appropriately inserted afterApplicationStarted. The ordering maintains thecommongroup and aligns with the documentation of the event ID shift.v3/internal/runtime/desktop/@wailsio/runtime/src/event_types.ts (1)
208-208: Event type addition looks goodThe added
ApplicationLaunchedWithUrlevent type follows the proper naming convention and is correctly placed in the Common category since this feature works across all supported platforms.v3/internal/commands/updatable_build_assets/darwin/Info.plist.tmpl (1)
49-63: Well-implemented macOS URL scheme registrationThe implementation for macOS custom protocol handling is correctly done by adding the
CFBundleURLTypesentry to the Info.plist template. The conditional block and template variable usage is consistent with the rest of the file.v3/examples/custom-protocol-example/frontend/bindings/github.com/wailsapp/wails/v3/examples/custom-protocol-example/index.js (1)
1-8: Auto-generated binding file looks goodThis file correctly imports and re-exports the
GreetServicemodule, making it available for the frontend. As noted in the comments, this is an auto-generated file that shouldn't be manually edited.v3/internal/commands/updatable_build_assets/linux/nfpm/nfpm.yaml.tmpl (1)
31-36: Well-structured Linux package post-installation handlingThe addition of the
scriptssection with apostinstallscript is a good approach to ensure the Linux desktop database gets updated after installing the package. This is essential for proper recognition of custom protocol handlers on Linux systems.You've also thoughtfully included commented placeholders for other lifecycle hooks that might be needed in the future.
v3/pkg/events/events_darwin.h (2)
9-140: Systematic event ID incrementation to accommodate new eventAll event constant definitions have been incremented by 1 to accommodate the new
ApplicationLaunchedWithUrlevent in the event sequence. The changes are consistent and systematic across all event constants.This approach maintains compatibility with existing event handlers while integrating the new custom protocol functionality.
142-142: Correctly updated MAX_EVENTS macroThe MAX_EVENTS macro has been properly incremented from 1188 to 1189 to reflect the addition of the new event. This ensures that memory allocations and event handling logic will have the correct upper bounds.
v3/examples/custom-protocol-example/frontend/bindings/github.com/wailsapp/wails/v3/examples/custom-protocol-example/greetservice.js (1)
1-15: Auto-generated binding looks correctThe binding file provides a clean interface for calling the
Greetmethod from JavaScript. The TypeScript annotations improve developer experience with type checking, and the function correctly returns a cancellable promise.As an auto-generated file, this follows the expected Wails binding patterns.
v3/internal/commands/build_assets/linux/nfpm/scripts/postinstall.sh (1)
1-22: Approve script for updating desktop and MIME databases.The POSIX-compliant
postinstall.shcorrectly checks forupdate-desktop-databaseandupdate-mime-database, emits warnings if missing, and exits successfully. This covers the critical step of registering.desktopentries and custom protocol MIME types after installation.v3/examples/custom-protocol-example/frontend/package.json (1)
1-17: Approve frontend package configuration.The
package.jsonsets up Vite for dev, build, and preview, pins the Wails runtime, and marks the project as private. This aligns with best practices for an example project.v3/internal/commands/updatable_build_assets/linux/desktop.tmpl (2)
1-11: Approve Linux desktop entry template.The static fields (
Name,Comment,Exec %u,Icon, etc.) follow the.desktopspec correctly and will pass the URL via%u.
13-15: Approve conditional MimeType block.The
{{if .Info.Protocols}}…{{end}}block properly generatesx-scheme-handler/{scheme}entries per protocol, enabling deep-link registration.v3/examples/custom-protocol-example/Taskfile.yml (2)
13-33: Well-structured task organization for cross-platform developmentThe task structure efficiently uses platform-specific delegation with
{{OS}}variable, providing a clean abstraction for build, package, and run operations across different operating systems. This aligns well with the cross-platform nature of the deep-linking feature being implemented.
3-7: Good separation of platform-specific build configurationsIncluding separate taskfiles for each platform (common, Windows, Darwin, Linux) follows best practices for organizing cross-platform build systems. This separation will make it easier to maintain the platform-specific protocol handler implementations.
v3/examples/custom-protocol-example/frontend/src/main.js (2)
31-35: Event handling is properly implementedGood implementation of the event listener for receiving URL data from the backend. The code correctly logs received data and updates the UI accordingly.
16-18: Protocol scheme matches configurationThe example URL
wailsexample://test/path?value=123&message=hellocorrectly demonstrates the custom protocol format. This aligns with the PR objectives for handling custom URL protocols.v3/pkg/application/application_darwin.go (2)
60-61: Good registration of custom protocol handlerAdding the custom protocol handler registration in the init method ensures it's set up early in the application lifecycle. This aligns with macOS expectations for registering URL handlers.
398-409: Well-implemented URL protocol handler for macOSThe
HandleCustomProtocolfunction correctly:
- Converts the C string URL to a Go string
- Creates an event context and sets the URL information
- Emits the cross-platform
ApplicationLaunchedWithUrleventThis implementation follows established patterns in the codebase and provides a consistent event across platforms as mentioned in the PR objectives.
v3/examples/custom-protocol-example/build/darwin/Info.dev.plist (1)
31-41: Custom URL scheme registration looks correctThe custom URL scheme registration for "wailsexample" looks correct and follows the macOS requirements for registering a URL handler.
v3/examples/custom-protocol-example/build/darwin/Info.plist (1)
26-36: Custom URL scheme registration looks correctThe custom URL scheme registration for "wailsexample" looks correct and follows the macOS requirements for registering a URL handler.
v3/examples/custom-protocol-example/main.go (2)
44-47: Custom protocol handling looks goodThe implementation correctly listens for the
ApplicationLaunchedWithUrlevent and forwards the URL to the frontend via an event emission.
34-34:Details
✅ Verification successful
Verify GreetService implementation
The code imports
GreetService, but its implementation isn't shown in this file. Ensure it exists and is properly defined elsewhere (likely ingreetservice.go).
🏁 Script executed:
#!/bin/bash # Check if the GreetService is defined in another file fd "GreetService" --type file --exec grep -A 10 "type GreetService" {} \;Length of output: 284
GreetService implementation verified
TheGreetServicetype and itsGreetmethod are defined ingreetservice.go. No further changes needed.v3/examples/custom-protocol-example/build/config.yml (1)
61-64: The custom protocol configuration looks goodThe protocol configuration correctly defines the "wailsexample" scheme with an appropriate description, which aligns with the PR's objective to support custom URL protocols.
v3/pkg/application/application_darwin_delegate.h (3)
16-18: Well-structured protocol handling declarationGood implementation of the function declaration for handling custom protocol URLs on macOS. This complements the existing file open handling.
19-22: Good Objective-C interface designThe
CustomProtocolSchemeHandlerinterface with the Apple Event handler method follows good Objective-C practices and provides the necessary functionality for handling URL scheme events.
23-23: Well-defined initialization methodThe
StartCustomProtocolHandlerfunction declaration follows the same pattern as other initialization functions in this file, maintaining consistency.v3/pkg/application/application_windows.go (4)
10-10: Good import additionAppropriate addition of the
stringsimport to support the URL detection logic.
148-177: Well-implemented command line parsing logicThe implementation correctly detects and handles command line arguments that could be custom protocol URLs or file associations. The logic is clear and well-structured, with detailed logging to aid debugging.
The approach of using
strings.Contains(arg1, "://")for URL detection is straightforward and appropriate for this use case.
396-398: Improved code formattingThe formatting changes to the function call improve readability by breaking the long line into multiple lines.
413-415: Consistent formatting improvementSimilar to the previous formatting change, this improves readability for long function calls.
v3/pkg/application/application_linux.go (1)
179-182: Improved log formattingGood improvement to the formatting of the DBus connection error log message, making it more readable.
v3/examples/custom-protocol-example/build/darwin/Taskfile.yml (1)
1-77: Well-structured Darwin build configuration for custom protocol exampleThis Taskfile.yml provides a comprehensive set of tasks for building, packaging, and running the custom protocol example application on macOS. The configuration properly handles:
- Architecture-specific builds (arm64, amd64, and universal binary)
- Proper macOS deployment target specification (10.15)
- App bundle creation with appropriate structure
- Development vs. production builds
- Code signing with ad-hoc identity
The implementation follows best practices for macOS application packaging and aligns well with the custom protocol feature being added.
v3/pkg/events/events_linux.h (2)
9-16: Event ID increments aligned with new URL protocol eventThe event IDs have been correctly incremented by 1 to accommodate the new
ApplicationLaunchedWithUrlevent mentioned in the PR description.
18-18: MAX_EVENTS properly updatedThe MAX_EVENTS constant has been correctly updated to 1057 to reflect the new event count.
v3/internal/commands/build-assets.go (5)
24-30: Good design for protocol configuration structureThe
ProtocolConfigstruct is well-designed with:
- Essential fields for scheme and description
- Proper JSON/YAML tags with omitempty for optional fields
- Forward-thinking comments about potential platform-specific extensions
This structure provides a solid foundation for the custom protocol feature.
52-52: Protocol configuration properly integrated into BuildConfigThe Protocols field has been correctly added to the BuildConfig struct.
146-146: Protocol configuration properly integrated into UpdateConfigThe Protocols field has been correctly added to the UpdateConfig struct.
161-161: Protocol configuration properly integrated into WailsConfigThe Protocols field has been correctly added to the WailsConfig struct.
194-194: Correctly populating protocols from Wails configurationThe code properly assigns the protocols from the parsed configuration to the UpdateConfig struct.
v3/pkg/application/application_darwin_delegate.m (3)
4-4: Properly importing CoreServices for Apple Event constantsThe CoreServices header is correctly imported to access the Apple Event constants needed for URL scheme handling.
184-191: Well-implemented custom protocol handler for Apple EventsThe
CustomProtocolSchemeHandlerclass properly implements the Apple Event handling mechanism for URL schemes:
- Correctly extracts the URL from the event descriptor
- Safely passes the URL string to the native HandleCustomProtocol function
This implementation follows Apple's recommended approach for handling custom URL schemes.
192-198: Good initialization of the custom protocol handlerThe
StartCustomProtocolHandlerfunction correctly:
- Gets the shared Apple Event Manager
- Registers the handler class and selector for Internet events
- Uses proper event class (kInternetEventClass) and event ID (kAEGetURL)
This ensures the application will properly receive URL scheme launch events.
v3/examples/custom-protocol-example/build/Taskfile.yml (2)
10-21: Frontend dependency installation is skippedI notice that the frontend dependency installation task is configured to simply output a message and skip the actual installation. While this may be intentional for this example project, it could be confusing for users trying to learn from this example.
Is this intentional for the example project or should actual dependency installation commands be included? If intentional, consider adding a comment explaining why (e.g., "Example has no frontend dependencies").
1-86: Overall Taskfile structure is well-definedThe Taskfile is well-structured with clear task definitions, dependencies, and outputs. It provides a comprehensive set of tasks for building and running the custom protocol example application.
v3/examples/custom-protocol-example/build/windows/Taskfile.yml (4)
13-18: Good cross-platform file cleanupThe task handles .syso file cleanup differently based on the platform, which is a good practice. This ensures the build process works correctly on Windows, Linux, and macOS development environments.
32-38: Architecture-aware syso generationThe syso generation task correctly passes the architecture parameter, ensuring that the right resources are embedded for different CPU architectures.
40-53: NSIS installer generation appears completeThe task for creating the NSIS installer includes all necessary steps:
- Generating the WebView2 bootstrapper
- Setting architecture-specific flags
- Running makensis with the appropriate parameters
This ensures proper packaging for Windows distribution with custom protocol support.
55-57: Simple run commandThe run task is straightforward and simply executes the built binary. This is appropriate for an example application.
v3/examples/custom-protocol-example/build/windows/nsis/project.nsi (5)
3-19: Well-documented NSIS scriptThe header comments provide clear instructions on how to use the script both within the Wails ecosystem and for manual debugging/development. This is excellent documentation practice.
34-47: Proper version information setupThe script correctly sets up version information for the installer using VIProductVersion and VIAddVersionKey. This ensures that Windows properly displays version and product metadata for the installed application.
48-50: HiDPI support enabledThe
ManifestDPIAware truesetting ensures the installer will display correctly on high-DPI displays, which is increasingly important for modern Windows applications.
94-97: File association integrationThe script calls the
wails.associateFilesmacro which will handle registering the custom URL protocol handlers in the Windows registry. This is a key part of implementing the deep linking functionality.
99-112: Complete uninstaller implementationThe uninstaller section properly cleans up everything installed by the installer, including:
- WebView2 data path
- Installed files
- Shortcuts
- File associations
This ensures a clean uninstallation experience.
v3/pkg/events/events.go (4)
10-12: New ApplicationLaunchedWithUrl event addedThe new event is correctly positioned in the commonEvents struct, which will be used to signal when the application is launched via a custom URL protocol.
39-63: Event ID sequencing updatedAll common event IDs have been correctly incremented after the insertion of the new ApplicationLaunchedWithUrl event. This maintains the requirement for unique event IDs throughout the framework.
79-461: Platform-specific event IDs adjustedAll platform-specific event IDs (Linux, Mac, Windows) have been incremented to account for the new common event. This is necessary to maintain the integrity of the event system.
10-678:Details
❓ Verification inconclusive
Verify event handling implementation across platforms
The addition of the ApplicationLaunchedWithUrl event is a significant feature that needs to work across all supported platforms. Make sure there's proper implementation and testing for this event in:
- macOS: URL handling via Info.plist CFBundleURLTypes
- Windows: Command-line argument parsing for URL protocols
- Linux: Desktop file associations and command-line parsing
🏁 Script executed:
#!/bin/bash # Verify implementation of URL handling across platforms # Check for platform-specific URL handling code echo "Checking for macOS implementation..." rg -A 5 "ApplicationLaunchedWithUrl" "v3/pkg/application/application_darwin.go" echo "Checking for Windows implementation..." rg -A 5 "ApplicationLaunchedWithUrl" "v3/pkg/application/application_windows.go" echo "Checking for Linux implementation..." rg -A 5 "ApplicationLaunchedWithUrl" "v3/pkg/application/application_linux.go" # Check for URL context implementation echo "Checking for URL context implementation..." rg -A 3 "URL()" "v3/pkg/application/"Length of output: 89171
URL handling wired up on macOS, Windows and Linux – please verify packaging & tests
- macOS
• CustomProtocolSchemeHandler in application_darwin_delegate.{h,m} registers the kAEGetURL AppleEvent
• StartCustomProtocolHandler() and processURLRequest() in application_darwin.go emit ApplicationLaunchedWithUrl- Windows
• application_windows.go checksstrings.Contains(arg, "://"), sets URL via ApplicationEventContext.setURL, and raises ApplicationLaunchedWithUrl- Linux
• application_linux.go uses the same “://” check, populates ApplicationEventContext and fires ApplicationLaunchedWithUrl- Event context
• context_application_event.go implements setURL() and URL() accessorsNext steps:
- Add a CFBundleURLTypes entry to your macOS Info.plist for your custom URL scheme
- Add or update unit/integration tests on each platform to cover the new ApplicationLaunchedWithUrl event
| APP_DIR="${APP_NAME}.AppDir" | ||
|
|
||
| # Create AppDir structure | ||
| mkdir -p "${APP_DIR}/usr/bin" | ||
| cp -r "${APP_BINARY}" "${APP_DIR}/usr/bin/" | ||
| cp "${ICON_PATH}" "${APP_DIR}/" | ||
| cp "${DESKTOP_FILE}" "${APP_DIR}/" | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add validation for required environment variables and robust error handling.
The script assumes that APP_NAME, APP_BINARY, ICON_PATH, and DESKTOP_FILE are set externally. To avoid silent failures or copying the wrong files, add explicit checks at the top:
: "${APP_NAME:?Environment variable APP_NAME must be set}"
: "${APP_BINARY:?Environment variable APP_BINARY must be set}"
: "${ICON_PATH:?Environment variable ICON_PATH must be set}"
: "${DESKTOP_FILE:?Environment variable DESKTOP_FILE must be set}"This ensures the script exits with a clear message if any are missing.
🤖 Prompt for AI Agents
In v3/examples/custom-protocol-example/build/linux/appimage/build.sh around
lines 9 to 16, the script uses environment variables APP_NAME, APP_BINARY,
ICON_PATH, and DESKTOP_FILE without validating their presence, which can cause
silent failures. Add explicit checks at the top of the script using parameter
expansion with error messages for each variable to ensure the script exits
immediately with a clear message if any required variable is not set.
| # Rename the generated AppImage | ||
| mv "${APP_NAME}*.AppImage" "${APP_NAME}.AppImage" | ||
|
|
There was a problem hiding this comment.
Fix wildcard expansion in the rename step.
Quoting the glob prevents shell expansion, so the rename will fail:
- mv "${APP_NAME}*.AppImage" "${APP_NAME}.AppImage"
+ mv ${APP_NAME}*.AppImage "${APP_NAME}.AppImage"Also consider guarding against multiple matches or missing files.
🤖 Prompt for AI Agents
In v3/examples/custom-protocol-example/build/linux/appimage/build.sh around
lines 33 to 35, the rename command uses a quoted wildcard which prevents shell
expansion, causing the rename to fail. Remove the quotes around the wildcard to
allow proper glob expansion. Additionally, add checks to handle cases where
multiple files match the pattern or no files are found, to avoid unexpected
behavior or errors during the rename step.
| # scripts: | ||
| # preinstall: ./build/linux/nfpm/scripts/preinstall.sh | ||
| # postinstall: ./build/linux/nfpm/scripts/postinstall.sh | ||
| # preremove: ./build/linux/nfpm/scripts/preremove.sh | ||
| # postremove: ./build/linux/nfpm/scripts/postremove.sh |
There was a problem hiding this comment.
Enable the postinstall script to update desktop and MIME databases.
The scripts block is currently commented out, so postinstall.sh will never run. Uncomment and point to the script you added:
scripts:
postinstall: ./build/linux/nfpm/scripts/postinstall.shWithout this, users won’t get their MIME database updated, breaking deep-link registration.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In v3/examples/custom-protocol-example/build/linux/nfpm/nfpm.yaml around lines
46 to 50, the scripts block is commented out, preventing the postinstall.sh
script from running. Uncomment the scripts section and ensure the postinstall
entry points to ./build/linux/nfpm/scripts/postinstall.sh so that the desktop
and MIME databases are updated correctly after installation.
| a { | ||
| font-weight: 500; | ||
| color: #646cff; | ||
| text-decoration: inherit; | ||
| } | ||
| a:hover { | ||
| color: #535bf2; | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Duplicate CSS selectors for links found
The file contains duplicate selectors for a and a:hover with different styling values. The second occurrence (lines 64-71) will override the first (lines 16-23), potentially causing confusion or rendering inconsistencies.
-a {
- font-weight: 500;
- color: #646cff;
- text-decoration: inherit;
-}
-a:hover {
- color: #535bf2;
-}
/* Later in the file */
a {
color: #007bff;
text-decoration: none;
+ font-weight: 500;
}Also applies to: 64-71
🤖 Prompt for AI Agents
In v3/examples/custom-protocol-example/frontend/src/style.css between lines
16-23 and 64-71, there are duplicate CSS selectors for 'a' and 'a:hover' with
conflicting styles. To fix this, consolidate the styles for these selectors into
a single block each, merging or choosing the appropriate properties to avoid
overrides and confusion. Remove the redundant duplicate selectors so that each
selector appears only once with the intended styles.
| <key>CFBundlePackageType</key> | ||
| <string>APPL</string> | ||
| <key>CFBundleName</key> | ||
| <string>My Product</string> |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Replace placeholder values with actual product information
The file contains generic placeholder values ("My Product", "com.mycompany.myproduct", etc.) and a future copyright year (2025) that should be replaced with actual information for this example.
- <key>CFBundleName</key>
- <string>My Product</string>
+ <key>CFBundleName</key>
+ <string>Custom Protocol Example</string>
- <key>CFBundleIdentifier</key>
- <string>com.mycompany.myproduct</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.wailsapp.custom-protocol-example</string>
- <key>CFBundleGetInfoString</key>
- <string>Some Product Comments</string>
+ <key>CFBundleGetInfoString</key>
+ <string>Example application demonstrating custom protocol handling</string>
- <key>NSHumanReadableCopyright</key>
- <string>(c) 2025, My Company</string>
+ <key>NSHumanReadableCopyright</key>
+ <string>(c) 2023, Wails</string>Also applies to: 11-11, 15-15, 25-25
🤖 Prompt for AI Agents
In v3/examples/custom-protocol-example/build/darwin/Info.dev.plist at lines 7,
11, 15, and 25, replace all placeholder values such as "My Product",
"com.mycompany.myproduct", and the copyright year "2025" with the actual product
name, bundle identifier, and current copyright year relevant to this example
project to ensure accurate and meaningful metadata.
| - (BOOL)applicationShouldHandleReopen:(NSNotification *)notification | ||
| hasVisibleWindows:(BOOL)flag { | ||
| hasVisibleWindows:(BOOL)flag { // Changed from NSApplication to NSNotification | ||
| if( hasListeners(EventApplicationShouldHandleReopen) ) { |
There was a problem hiding this comment.
Fix incorrect parameter type in applicationShouldHandleReopen method
The parameter type for the applicationShouldHandleReopen method has been changed from NSApplication * to NSNotification *, which doesn't match Apple's NSApplicationDelegate protocol definition.
According to Apple's documentation, the correct signature should be:
-- (BOOL)applicationShouldHandleReopen:(NSNotification *)notification
- hasVisibleWindows:(BOOL)flag { // Changed from NSApplication to NSNotification
+- (BOOL)applicationShouldHandleReopen:(NSApplication *)sender
+ hasVisibleWindows:(BOOL)flag {This could cause unexpected behavior when the application is reopened.
🤖 Prompt for AI Agents
In v3/pkg/application/application_darwin_delegate.m around lines 44 to 46, the
method applicationShouldHandleReopen has an incorrect parameter type
NSNotification * instead of NSApplication *. Change the first parameter type
back to NSApplication * to match Apple's NSApplicationDelegate protocol
definition and ensure correct behavior when the application is reopened.
| vars: | ||
| BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -buildvcs=false -ldflags="-w -s"{{else}}-buildvcs=false -gcflags=all="-l"{{end}}' | ||
| env: | ||
| GOOS: linux | ||
| CGO_ENABLED: 1 | ||
| GOARCH: '{{.ARCH | default ARCH}}' | ||
| PRODUCTION: '{{.PRODUCTION | default "false"}}' |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Incorrect defaulting of GOARCH may yield empty or invalid builds
'{{.ARCH | default ARCH}}' attempts to default to the string literal ARCH, not the env-var/content of .ARCH.
If callers don’t pass an ARCH variable, the resulting GOARCH will literally be “ARCH”, causing the build to fail.
- GOARCH: '{{.ARCH | default ARCH}}'
+ # Use sprig's `default` to fall back to amd64 when .ARCH is not provided
+ GOARCH: '{{ default "amd64" .ARCH }}'📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| vars: | |
| BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -buildvcs=false -ldflags="-w -s"{{else}}-buildvcs=false -gcflags=all="-l"{{end}}' | |
| env: | |
| GOOS: linux | |
| CGO_ENABLED: 1 | |
| GOARCH: '{{.ARCH | default ARCH}}' | |
| PRODUCTION: '{{.PRODUCTION | default "false"}}' | |
| vars: | |
| BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -buildvcs=false -ldflags="-w -s"{{else}}-buildvcs=false -gcflags=all="-l"{{end}}' | |
| env: | |
| GOOS: linux | |
| CGO_ENABLED: 1 | |
| # Use sprig's `default` to fall back to amd64 when .ARCH is not provided | |
| GOARCH: '{{ default "amd64" .ARCH }}' | |
| PRODUCTION: '{{.PRODUCTION | default "false"}}' |
🤖 Prompt for AI Agents
In v3/examples/custom-protocol-example/build/linux/Taskfile.yml around lines 14
to 20, the GOARCH variable is incorrectly defaulted to the string literal "ARCH"
instead of the value of the ARCH environment variable. To fix this, change the
default expression to use an actual default value like "amd64" or another valid
architecture string instead of "ARCH" so that if .ARCH is not provided, GOARCH
gets a valid default and the build does not fail.
| func (c *ApplicationEventContext) setData(data map[string]any) { | ||
| c.data = data | ||
| } | ||
|
|
||
| func (c ApplicationEventContext) setOpenedWithFile(filepath string) { | ||
| func (c *ApplicationEventContext) setOpenedWithFile(filepath string) { | ||
| c.data[filename] = filepath | ||
| } |
There was a problem hiding this comment.
Possible nil-map panic when setters are used on an un-initialised context
blankApplicationEventContext is created with data == nil.
Calling any setter (setURL, setOpenedFiles, …) on such a context will panic because writing to a nil map is invalid.
Safest fix: lazily initialise in each setter:
if c.data == nil {
c.data = make(map[string]any)
}Add this guard to all setter methods.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In v3/pkg/application/context_application_event.go around lines 62 to 68, the
setter methods assign values to the c.data map without checking if it is
initialized, which can cause a nil-map panic. To fix this, add a check at the
start of each setter method to initialize c.data as an empty map if it is nil
before assigning any values. This lazy initialization will prevent panics when
setters are called on an uninitialized context.
| ${If} ${AtLeastWin10} | ||
| !ifdef SUPPORTS_AMD64 | ||
| ${if} ${IsNativeAMD64} | ||
| Goto ok | ||
| ${EndIf} | ||
| !endif | ||
|
|
||
| !ifdef SUPPORTS_ARM64 | ||
| ${if} ${IsNativeARM64} | ||
| Goto ok | ||
| ${EndIf} | ||
| !endif |
There was a problem hiding this comment.
LogicLib keyword uses lowercase ${if} – NSIS will fail to compile
LogicLib is case-sensitive; use ${If}/${EndIf}.
The two blocks showing the issue:
${if} ${IsNativeAMD64} ; invalid
...
${if} ${IsNativeARM64} ; invalid- ${if} ${IsNativeAMD64}
+ ${If} ${IsNativeAMD64}
...
- ${if} ${IsNativeARM64}
+ ${If} ${IsNativeARM64}Same problem occurs again in the wails.files macro; patch both locations.
🤖 Prompt for AI Agents
In v3/examples/custom-protocol-example/build/windows/nsis/wails_tools.nsh around
lines 67 to 78, the LogicLib conditional keywords `${if}` and `${EndIf}` are
incorrectly lowercase, causing NSIS compilation failure. Replace all instances
of `${if}` with `${If}` and `${EndIf}` with `${EndIf}` (proper casing) in these
blocks. Also, locate the same incorrect usage in the `wails.files` macro within
this file and apply the same casing corrections to ensure successful
compilation.
| # Copy of APP_ASSOCIATE and APP_UNASSOCIATE macros from here https://gist.github.com/nikku/281d0ef126dbc215dd58bfd5b3a5cd5b | ||
| !macro APP_ASSOCIATE EXT FILECLASS DESCRIPTION ICON COMMANDTEXT COMMAND | ||
| ; Backup the previously associated file class | ||
| ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" "" | ||
| WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "${FILECLASS}_backup" "$R0" | ||
|
|
||
| WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "${FILECLASS}" | ||
|
|
||
| WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}" "" `${DESCRIPTION}` | ||
| WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\DefaultIcon" "" `${ICON}` | ||
| WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell" "" "open" | ||
| WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\open" "" `${COMMANDTEXT}` | ||
| WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\open\command" "" `${COMMAND}` | ||
| !macroend | ||
|
|
||
| !macro APP_UNASSOCIATE EXT FILECLASS | ||
| ; Backup the previously associated file class | ||
| ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" `${FILECLASS}_backup` | ||
| WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "$R0" | ||
|
|
||
| DeleteRegKey SHELL_CONTEXT `Software\Classes\${FILECLASS}` | ||
| !macroend |
There was a problem hiding this comment.
Undefined constant SHELL_CONTEXT will break registry operations
WriteRegStr SHELL_CONTEXT ... relies on a compile-time constant that is never !defined.
Define it once depending on REQUEST_EXECUTION_LEVEL (admin ⇒ HKLM, user ⇒ HKCU) so file-association macros work:
+# Determine registry root based on installer elevation
+!ifndef SHELL_CONTEXT
+ !if "${REQUEST_EXECUTION_LEVEL}" == "admin"
+ !define SHELL_CONTEXT "HKLM"
+ !else
+ !define SHELL_CONTEXT "HKCU"
+ !endif
+!endifPlace this before the first use of SHELL_CONTEXT.
🤖 Prompt for AI Agents
In v3/examples/custom-protocol-example/build/windows/nsis/wails_tools.nsh around
lines 181 to 202, the constant SHELL_CONTEXT used in registry operations is not
defined, causing failures. Define SHELL_CONTEXT before its first use based on
REQUEST_EXECUTION_LEVEL: set it to HKLM if admin level is requested, otherwise
set it to HKCU. This ensures the file association macros correctly target the
appropriate registry hive.
|
|
Thanks @atterpac 🎉 |
V3 Deep-link (Port of v2 feature)



This is a loose port of the v2 Custom Protocol Association feature initially introduced in #3000
There are some modification to how a user will use the API but the logic of gathering it is fairly similar
A unified Golang API for it is provided to the user regardless of OS as opposed to the v2 solution
I have tested on macOS but will need assistance to confirm/troubleshoot other OS, will include my hardware details below
Setting up custom protocol
Configuring the custom protocol is set inside the wails config file
{ "name": "My App", "description": "An amazing Wails app!", "info": { "companyName": "My Company", "productName": "My Product", "protocols": [ { "scheme": "myapp", "description": "My Application Custom Protocol" }, { "scheme": "anotherprotocol", "description": "Another protocol for specific actions" } ] } }How it works
The config file will take care of most of the setup for you you will need to run
task common:update:build-assetsonce updating your config file for the changes to take placeIn all OS you will need a
task packagebuild in order for the custom protocol to work.MacOS
Values are taken from the config file to populate the correct fields inside the plist
Windows
**Requires an NSIS install step and
makensis**Windows will add the URL as an argument to the launch args, wails checks this on start up any launch args match your deep link protocol if so the application event is emitted saving you from having to parse and determine yourself.
Linux
Requires an install step
Linux is setup to configure your deep-link via nfpm and a .desktop file, on install the
post-install.shscript will update the device database and MIME types to allow for deep linking.Linux works similar to windows as it passes the url as an argument to the launch. Wails handles is the same way to populate the application event
Hardware details
Summary by CodeRabbit
New Features
Documentation
Chores