wails icon indicating copy to clipboard operation
wails copied to clipboard

[V3] Add universal link support for macOS

Open APshenkin opened this issue 5 months ago • 9 comments

Description

This PR backports https://github.com/wailsapp/wails/pull/4693/files to V3

Fixes # (issue)

Type of change

Please select the option that is relevant.

  • [ ] Bug fix (non-breaking change which fixes an issue)
  • [x] New feature (non-breaking change which adds functionality)
  • [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • [ ] This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration using wails doctor.

  • [ ] Windows
  • [x] macOS
  • [ ] Linux

If you checked Linux, please specify the distro and version.

Test Configuration

# System

┌──────────────────────────────────────────────────┐
| Name          | MacOS                            |
| Version       | 26.1                             |
| ID            | 25B78                            |
| Branding      | MacOS 26.1                       |
| Platform      | darwin                           |
| Architecture  | arm64                            |
| Apple Silicon | true                             |
| CPU           | Apple M4 Max                     |
| CPU 1         | Apple M4 Max                     |
| CPU 2         | Apple M4 Max                     |
| GPU           | 40 cores, Metal Support: Metal 4 |
| Memory        | 128 GB                           |
└──────────────────────────────────────────────────┘

# Build Environment

┌─────────────────────────────────────────────────────────┐
| Wails CLI    | v3.0.0-dev                               |
| Go Version   | go1.24.0                                 |
| Revision     | 4a445ce218b58db4a16ee8fa84eac0d7c9a69932 |
| Modified     | false                                    |
| -buildmode   | exe                                      |
| -compiler    | gc                                       |
| CGO_CFLAGS   |                                          |
| CGO_CPPFLAGS |                                          |
| CGO_CXXFLAGS |                                          |
| CGO_ENABLED  | 1                                        |
| CGO_LDFLAGS  |                                          |
| GOARCH       | arm64                                    |
| GOARM64      | v8.0                                     |
| GOOS         | darwin                                   |
| vcs          | git                                      |
| vcs.modified | false                                    |
| vcs.revision | 4a445ce218b58db4a16ee8fa84eac0d7c9a69932 |
| vcs.time     | 2025-08-04T22:42:25Z                     |
└─────────────────────────────────────────────────────────┘

# Dependencies

┌────────────────────────────────────────────────────────────────────────┐
| Xcode cli tools | 2416                                                 |
| npm             | 10.9.2                                               |
| *NSIS           | Not Installed. Install with `brew install makensis`. |
|                                                                        |
└─────────────────────── * - Optional Dependency ────────────────────────┘

Please paste the output of wails doctor. If you are unable to run this command, please describe your environment in as much detail as possible.

Checklist:

  • [ ] I have updated website/src/pages/changelog.mdx with details of this PR
  • [x] My code follows the general coding style of this project
  • [x] I have performed a self-review of my own code
  • [x] I have commented my code, particularly in hard-to-understand areas
  • [ ] I have made corresponding changes to the documentation
  • [x] My changes generate no new warnings
  • [ ] I have added tests that prove my fix is effective or that my feature works
  • [x] New and existing unit tests pass locally with my changes

Summary by CodeRabbit

  • New Features

    • Added Universal Link / web URL continuation on macOS so apps can open directly from supported web links.
  • Refactor

    • Unified macOS URL handling and Apple Event processing, preserving existing window-reopen behavior.
  • Documentation

    • Added cross-platform guidance for Universal Links and Web-to-App linking with configuration and hosting examples for macOS and Windows.

✏️ Tip: You can customize this high-level summary in your review settings.

APshenkin avatar Nov 14 '25 18:11 APshenkin

Walkthrough

Renames the C-exported URL handler from HandleCustomProtocol to HandleOpenURL, adds macOS Universal Link support via application:continueUserActivity:restorationHandler:, updates Apple Event URL handling to call the new entry, removes an obsolete secure restorable state declaration, and adjusts a reopen method signature.

Changes

Cohort / File(s) Summary
Go export rename
v3/pkg/application/application_darwin.go
Exported C bridge renamed: HandleCustomProtocol(urlCString *C.char)HandleOpenURL(urlCString *C.char) (behavior unchanged).
Objective‑C header updates
v3/pkg/application/application_darwin_delegate.h
Replaced extern void HandleCustomProtocol(char*); with extern void HandleOpenURL(char*);, removed - (BOOL)applicationSupportsSecureRestorableState:(NSApplication *)app;, added + (void)handleGetURLEvent:withReplyEvent:, and updated comment to include Universal Link support.
Delegate implementation changes
v3/pkg/application/application_darwin_delegate.m
Added application:continueUserActivity:restorationHandler: to handle Universal Links (calls HandleOpenURL), updated Apple Event handler to call HandleOpenURL, and changed applicationShouldHandleReopen:hasVisibleWindows: first parameter from NSApplication * to NSNotification *.
Docs & changelog
v3/UNRELEASED_CHANGELOG.md, docs/src/content/docs/guides/custom-protocol-association.mdx
Added changelog entry for macOS Universal Link support and expanded docs with Universal Links / Web-to-App linking guidance for macOS and Windows.

Sequence Diagram(s)

sequenceDiagram
    participant Apple as Apple OS
    participant Delegate as AppDelegate
    participant Go as Go runtime

    rect rgb(248,249,255)
    note over Apple,Delegate: Apple Event (Custom URL Scheme)
    Apple->>Delegate: handleGetURLEvent:withReplyEvent:
    Delegate->>Go: HandleOpenURL(urlString)
    Go->>Go: Parse URL & emit ApplicationLaunchedWithUrl
    end

    rect rgb(240,255,245)
    note over Apple,Delegate: Universal Link (NSUserActivity)
    Apple->>Delegate: application:continueUserActivity:restorationHandler:
    Delegate->>Delegate: verify NSUserActivityTypeBrowsingWeb & webpageURL
    Delegate->>Go: HandleOpenURL(webpageURL)
    Go->>Go: Parse URL & emit ApplicationLaunchedWithUrl
    end

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Confirm //export name and C symbol match between application_darwin.go and header.
  • Review application:continueUserActivity:restorationHandler: for nil checks and correct extraction of webpageURL.
  • Check callers and usages of applicationShouldHandleReopen: for compatibility with the changed first parameter.

Suggested labels

Enhancement, size:M, lgtm

Suggested reviewers

  • leaanthony

Poem

🐰 I hopped through Darwin's apple tree,
A tiny URL came bounding to me,
Schemes and web links now share one way,
HandleOpenURL saves the day—hooray! 🥕

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding universal link support for macOS in V3.
Description check ✅ Passed The description follows the template structure with completed sections including type of change (new feature), test configuration (macOS tested), and most checklist items. However, documentation updates and changelog.mdx update are marked incomplete.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • [ ] Create PR with unit tests
  • [ ] Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 11b04a13daa080cfaecf2c321f213fd85b0fcb7a and dc5bb340528dab61f0ac3cc68c30d490d0548c4d.

📒 Files selected for processing (1)
  • v3/UNRELEASED_CHANGELOG.md (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: APshenkin
Repo: wailsapp/wails PR: 4484
File: v2/internal/frontend/utils/urlValidator.go:25-31
Timestamp: 2025-08-08T13:15:20.339Z
Learning: In Wails v2 (PR wailsapp/wails#4484), for BrowserOpenURL URL validation (v2/internal/frontend/utils/urlValidator.go), maintainers (APshenkin) prefer not to restrict schemes to an http/https allowlist because supported schemes may vary. The allowlist suggestion is declined; continue with the existing denylist approach and generic validation.
📚 Learning: 2025-08-08T13:15:20.339Z
Learnt from: APshenkin
Repo: wailsapp/wails PR: 4484
File: v2/internal/frontend/utils/urlValidator.go:25-31
Timestamp: 2025-08-08T13:15:20.339Z
Learning: In Wails v2 (PR wailsapp/wails#4484), for BrowserOpenURL URL validation (v2/internal/frontend/utils/urlValidator.go), maintainers (APshenkin) prefer not to restrict schemes to an http/https allowlist because supported schemes may vary. The allowlist suggestion is declined; continue with the existing denylist approach and generic validation.

Applied to files:

  • v3/UNRELEASED_CHANGELOG.md
⏰ 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)
  • GitHub Check: Run Go Tests v3 (windows-latest, 1.24)
  • GitHub Check: Run Go Tests v3 (macos-latest, 1.24)
  • GitHub Check: Run Go Tests v3 (ubuntu-latest, 1.24)
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (1)
v3/UNRELEASED_CHANGELOG.md (1)

20-20: Changelog entry is well-formatted and compliant with guidelines.

The entry follows the "Keep a Changelog" format, uses present tense, provides a clear description, includes PR reference, and maintains consistency with adjacent entries in the file.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot] avatar Nov 14 '25 18:11 coderabbitai[bot]

Thanks 🙏 Please could you add an entry to the changelog located at v3/UNRELEASED_CHANGELOG.md? Thanks!

leaanthony avatar Nov 18 '25 19:11 leaanthony

@leaanthony added

APshenkin avatar Nov 19 '25 22:11 APshenkin

Would it be possible to have some short documentation on how to use this feature? I'm ok having that in a later PR if we make a ticket for it 👍 Will be updating the docs significantly over the weekend so I'm ok to delay it 👍

leaanthony avatar Nov 20 '25 20:11 leaanthony

@leaanthony happy to add docs for v3, however can't see v3 site docs in repo. Where should I add it?

APshenkin avatar Nov 24 '25 23:11 APshenkin

@leaanthony happy to add docs for v3, however can't see v3 site docs in repo. Where should I add it?

Amazing! 🎉 They are in docs at the project root. The taskfile here docs/Taskfile.yml has everything you need. Just pick your package manager. Use task setup and you should be good to go 👍

leaanthony avatar Nov 25 '25 09:11 leaanthony

@leaanthony added

APshenkin avatar Nov 25 '25 11:11 APshenkin

@leaanthony added. Was blind to not find folder with docs 😀

APshenkin avatar Nov 25 '25 11:11 APshenkin

Thanks for your patience again @APshenkin :pray:

leaanthony avatar Dec 08 '25 09:12 leaanthony

@leaanthony no problem, thank you for cooperation!

APshenkin avatar Dec 08 '25 10:12 APshenkin