blogccasion

Web Apps on macOS Sonoma 14 Beta

Executive summary

With macOS Sonoma, Apple goes all-in on the concept of installable web apps. They're highly integrated in the overall macOS experience and don't give away their web roots by not showing any Safari UI at all.

Testing environment

Tested on macOS Sonoma 14.0 Beta (23A5257q) with Safari version 17.0 (19616.1.14.11.11). It probably doesn't matter, but the testing device was a 13-inch, M1, 2020 MacBook Pro.

Install experience

On macOS Sonoma, you can add a websiteβ€”any website, not just apps with a manifestβ€”to your Dock. Go to the Share icon and click Add to Dock, or use the menu item File > Add to Dock.

Adding an app via the Share icon.

Adding an app via the Share icon.

Adding an app via the File menu.

Adding an app via the File menu.

You can adjust the name and icon if desired. The URL is the URL you're on for pages without a manifest, or the start_url for pages with a manifest. It can't be changed. For pages without an icon, Safari will create a fallback icon based on the first letter of the page's title.

πŸ‘€ Observation: Unlike on iOS/iPadOS, you can't add the same app twice, unless you rename it.

App name and icon are adjustable, the URL is not.

App name and icon are adjustable, the URL is not.

The web app icon then appears in your Dock. Maskable icons are supported, and the typical macOS squircle shape is respected. Closing all windows of an app leaves the app running, aligned with macOS UX paradigms.

πŸ‘€ Observation: Unlike on Chrome, the app doesn't launch immediately and "morph" from in-tab to in-app, but instead you remain on the tab and need to launch the app manually.

Web app added to the Dock.

Web app added to the Dock.

When right-clicking the Dock icon, you can uncheck Keep in Dock and still launch the app via Launchpad, Spotlight Search, or even just by double-clicking the app icon in ~/Applications/.

Launch experience

The out-of-the box launch experience of web apps is fantastic. Nowhere does it give away that this is a web app. For apps with a manifest, there's no Safari UI whatsoever, and the expectation is that such apps are single-page apps that provide their own navigation controls. If an app is well made, lay persons probably wouldn't be able to tell that something is a web app.

Web app running without any Safari UI.

Web app running without any Safari UI.

πŸ‘€ Observation: Different from iOS/iPadOS, credentials in cookies are copied over, so if you were logged in when running in the tab, you're logged in when you launch the app. No other storage means apart from cookies are copied. "When a user adds a website to their Dock, Safari will copy the website's cookies to the web app. That way, if someone is logged into their account in Safari, they will remain logged in within the web app. This will only work if the authentication state is stored within cookies. Safari does not copy over any other kind of local storage. After a user adds a web app to the Dock, no other website data is shared, which is great for privacy".

πŸ‘€ Observation: Web Inspector (DevTools) works a little differently than, for example, in Chrome: even with the Show features for web developers checkbox in Safari checked, there's no Develop menu item nor can you right-click and Inspect Element in a web app. Instead, you debug apps via Safari's Develop > $machineName > $appName menu item (thanks, @samedwards@mastodon.social). If all app windows are closed but the app isn't quit, a potential service worker will be inspectable until it gets terminated after a couple of seconds.

Debugging a web app via Safari.

Debugging a web app via Safari.

πŸ‘€ Observation: Extensions don't run and likewise aren't displayed. Also probably a conscious decision.

πŸ‘€ Observation: Same-origin (or in-scope if a manifest exists) links are handled in-app, cross-origin (or out-of-scope if a manifest exists) links open in the default browser. A notable exception are OAuth flow links, which are handled in-app based on a heuristic. Links opened via window.open() will always open in the web app.

If a user navigates to an already installed app in Safari, a prompt is displayed that invites the user to Open in web app.

Prompt inviting the user to Open in web app.

Prompt inviting the user to Open in web app.

macOS integration experience

Web apps on Mac let you focus on the websites you use all the time, separate from the rest of your browsing. Like all Mac apps, web apps work great with Stage Manager, Mission Control, and keyboard shortcuts like Command + Tab. Web apps can be opened from the Dock, Launchpad, and Spotlight Search.

Multitasking experience.

Multitasking experience.

Spotlight search experience.

Spotlight search experience.

Launchpad experience.

Launchpad experience.

Stage Manager experience.

Stage Manager experience.

All web apps have an About dialog.

All web apps have an About dialog.

Settings and permissions

Web apps work with AutoFill credentials from iCloud Keychain and from third-party apps that have adopted the Credential Provider Extension API. Users can grant permission to a web app to use their camera, microphone and location in the same way they grant such permissions to other Mac apps through system prompts and the Privacy & Security section of System Settings.

System settings with Camera permissions.

System settings with Camera permissions.

Web apps on Mac support web push, badging, and all the usual web standards implemented by WebKit, just like web apps on iOS and iPadOS.

πŸ‘€ Observation: There seems to be a bug where the hosting Web App appears as the app requesting the Notifications permission. Notifications then work as expected, though, including using the correct icon.

Notifications permission prompt with the wrong app name and icon.

Notifications permission prompt with the wrong app name and icon.

Web apps have their own Settings dialog. In General, the app name and icon can be changed and navigation controls can be toggled on or off. The theming behavior of the title bar can be changed, too.

πŸ‘€ Observation: Navigation controls are toggled off when there's a manifest with "display": "standalone". In all other cases, even if a manifest exists but with a different "display" mode, navigation controls are toggled on.

Web app Settings dialog on the General tab.Web app Settings dialog on the General tab.

πŸ‘€ Observation: There's currently a bug where web apps don't correctly report matchMedia('(display-mode: standalone)'). Added to the Dock web apps think they run in a tab.

With navigation controls enabled, there's an Open in Safari icon in the upper right corner. Despite its label, it actually respects the user's default browser.

Open in Safari icon.

Open in Safari icon.

Web pages get navigation affordances in the form of a back and forward button. There's no reload button.

Back and forward buttons.

Back and forward buttons.

πŸ‘€ Observation: With navigation controls toggled to off, the title of the web app sourced from the manifest is not shown. With navigation controls toggled to on, the title sourced from the <title> is shown.

πŸ‘€ Observation: When you right-click, there's a context menu with Reload or Back and Reload. This works independent from whether navigation controls are toggled on or off.

The Privacy tab allows the user to clear website data and links into the Privacy & Security Settings of the System Settings app.

Web app Settings dialog on the Privacy tab.

Web app Settings dialog on the Privacy tab.

Technical analysis

(See comment #7 of Chromium bug 1451667 for the full details.)

All apps are stored in ~/Applications/. The package contents of each apps are:

  • a _CodeSignature folder with code signature metadata
  • a Resources folder with just the app icons as a single ApplicationIcon.icns file
  • an Info.plist file.

The package contents of an app.

The package contents of an app.

The Info.plist file interestingly contains an XML version of key parts of the manifest and metadata about the app.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>CFBundleIconFile</key>
    <string>ApplicationIcon</string>
    <key>CFBundleIdentifier</key>
    <string
      >com.apple.Safari.WebApp.svgco.de.53298B34-AF7F-4074-9CA9-1EE46B7E3E83</string
    >
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>SVGcode</string>
    <key>CFBundlePackageType</key>
    <string>AAPL</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    <key>CFBundleSupportedPlatforms</key>
    <array>
      <string>MacOSX</string>
    </array>
    <key>CFBundleURLTypes</key>
    <array>
      <dict>
        <key>CFBundleURLSchemes</key>
        <array>
          <string>x-webkit-app-launch</string>
        </array>
        <key>LSHandlerRank</key>
        <string>None</string>
      </dict>
    </array>
    <key>CFBundleVersion</key>
    <string>1</string>
    <key>LSMinimumSystemVersion</key>
    <string>14.0</string>
    <key>LSTemplateApplication</key>
    <true />
    <key>LSTemplateApplicationParameters</key>
    <dict>
      <key>CFBundleIdentifier</key>
      <string>com.apple.Safari.WebApp</string>
      <key>TemplateAppUUID</key>
      <string>53298B34-AF7F-4074-9CA9-1EE46B7E3E83</string>
      <key>defaultarguments</key>
      <true />
      <key>teamIdentifier</key>
      <string></string>
    </dict>
    <key>Manifest</key>
    <dict>
      <key>description</key>
      <string
        >SVGcode is a Progressive Web App that lets you convert raster images
        like JPG, PNG, GIF, WebP, AVIF, etc. to vector graphics in SVG
        format.</string
      >
      <key>display</key>
      <string>standalone</string>
      <key>icons</key>
      <array>
        <dict>
          <key>purpose</key>
          <string>maskable</string>
          <key>sizes</key>
          <string>1024x1024</string>
          <key>src</key>
          <string>https://svgco.de/favicon.png</string>
          <key>type</key>
          <string>image/png</string>
        </dict>
        <dict>
          <key>purpose</key>
          <string>any</string>
          <key>sizes</key>
          <string>150x150</string>
          <key>src</key>
          <string>https://svgco.de/favicon.svg</string>
          <key>type</key>
          <string>image/svg+xml</string>
        </dict>
        <dict>
          <key>purpose</key>
          <string>monochrome</string>
          <key>sizes</key>
          <string>150x150</string>
          <key>src</key>
          <string>https://svgco.de/favicon-bw.svg</string>
          <key>type</key>
          <string>image/svg+xml</string>
        </dict>
      </array>
      <key>name</key>
      <string>SVGcode</string>
      <key>scope</key>
      <string>https://svgco.de</string>
      <key>short_name</key>
      <string>SVGcode</string>
      <key>start_url</key>
      <string>https://svgco.de/</string>
      <key>theme_color</key>
      <string>#ffffff</string>
    </dict>
    <key>WKPushBundleMetadata</key>
    <dict>
      <key>manifestId</key>
      <string>https://svgco.de/</string>
    </dict>
  </dict>
</plist>

Similar to iOS/iPadOS, web apps run in the context of a separate process called Web App.app, which resides in /System/Volumes/Preboot/Cryptexes/App/System/Library/CoreServices/Web App.app.

πŸ‘€ Observation: Separating Safari and Web App allows both to run independently. You can open a Web app without opening Safari, you can close Safari without all web apps closing.

The Web App.app app in Finder.

The Web App.app app in Finder.

Each web app runs as its own process of kind Web, accompanied by a number of helper processes of kind Apple. They can all be seen in Activity Monitor.

Activity Monitor showing all processes associated with a web app.

Activity Monitor showing all processes associated with a web app.

Wish list for Apple

(Also see Most wanted PWA features on iOS/iPadOS/macOS Safari.)

Spotify native app title bar experience.

Spotify native app title bar experience.

Spotify web app title bar experience.

Spotify web app title bar experience.

  • Add support for the File Handling API, so web apps can open files from Finder by double click if the web app is registered as the default file handler for a given file type, or by right click and then Open with if the web app can handle a file type, but isn't the default file handler. [🧭 257783]
  • Add support for the Launch Handler API, so web apps can decide how they want to handle launch events. [🧭 257785]
  • Reflect the cookie-copying logic on iOS/iPadOS. It's a very frustrating experience if you have to log in twice, even more so if two-factor authentication is involved. [🧭 257786]
  • Allow users to turn off the Open in web app prompt.

Recommendations for Chrome

  • Better respect macOS' design paradigms. Currently web app icon handling looks not integrated and icon shapes are all over the place. This is tracked as crbug/1230792. The examples below are all web apps installed via Chrome.

Web app icon shapes installed from Chrome don't respect the squircle.

Web app icon shapes installed from Chrome don't respect the squircle.

  • Move the extension puzzle piece and the Window Controls Overlay chevron into the three dots menu. Web apps can look so much cleaner without both in plain sight.

Window Controls Overlay chevron and extension puzzle piece clutter the UI of
Chrome-installed apps.

Window Controls Overlay chevron and extension puzzle piece clutter the UI of Chrome-installed apps.

New Fugu API needs

With Chrome and Safari now allowing web apps to be installed on macOS, it would be fantastic if installed apps could respect macOS UX guidelines and populate the system-level menu. Ideally Apple and Google engage jointly on the corresponding Project Fugu 🐑 API request tracked in crbug/1295253. The screenshots below show all menu items as per the current default.

Web app default app name menu.

Web app default app name menu.

Web app File menu.

Web app File menu.

Web app Edit menu.

Web app Edit menu.

Web app View menu.

Web app View menu.

Web app Go menu.

Web app Go menu.

Web app Window menu.

Web app Window menu.

Web app Help menu.

Web app Help menu.

Conclusion

Web apps in macOS Sonoma 14 Beta seamlessly integrate into the macOS experience, with no or very little visible Safari UI and with support for various operating system features. There is an enormous potential for web apps on macOS to succeed, and if Apple only works on a third of the items on my wish list, the potential is even bigger.