{"id":3484,"date":"2023-06-07T15:39:59","date_gmt":"2023-06-07T13:39:59","guid":{"rendered":"https:\/\/blog.tomayac.com\/2023\/06\/07\/web-apps-on-macos-sonoma-14-beta\/"},"modified":"2023-06-07T15:39:59","modified_gmt":"2023-06-07T13:39:59","slug":"web-apps-on-macos-sonoma-14-beta","status":"publish","type":"post","link":"https:\/\/tomayac.com\/wordpress\/2023\/06\/07\/web-apps-on-macos-sonoma-14-beta\/","title":{"rendered":"Web Apps on macOS Sonoma 14 Beta"},"content":{"rendered":"\n\t\t\t<h2 id=\"executive-summary\" tabindex=\"-1\">Executive summary <a class=\"direct-link\" href=\"https:\/\/blog.tomayac.com\/2023\/06\/07\/web-apps-on-macos-sonoma-14-beta\/#executive-summary\" aria-hidden=\"true\">\ud83d\udd17<\/a><\/h2>\n<p>With macOS Sonoma, <strong>Apple goes all-in on the concept of installable web apps<\/strong>.\nThey're highly integrated in the overall macOS experience and don't give away\ntheir web roots by not showing any Safari UI at all.<\/p>\n<h2 id=\"testing-environment\" tabindex=\"-1\">Testing environment <a class=\"direct-link\" href=\"https:\/\/blog.tomayac.com\/2023\/06\/07\/web-apps-on-macos-sonoma-14-beta\/#testing-environment\" aria-hidden=\"true\">\ud83d\udd17<\/a><\/h2>\n<p>Tested on macOS Sonoma 14.0 Beta (<code>23A5257q<\/code>) with Safari version 17.0\n(<code>19616.1.14.11.11<\/code>). It probably doesn't matter, but the testing device was a\n13-inch, M1, 2020 MacBook Pro.<\/p>\n<h2 id=\"install-experience\" tabindex=\"-1\">Install experience <a class=\"direct-link\" href=\"https:\/\/blog.tomayac.com\/2023\/06\/07\/web-apps-on-macos-sonoma-14-beta\/#install-experience\" aria-hidden=\"true\">\ud83d\udd17<\/a><\/h2>\n<p>On macOS Sonoma, you can add a website\u2014any website, not just apps with a\nmanifest\u2014to your Dock. Go to the <strong>Share<\/strong> icon and click <strong>Add to Dock<\/strong>, or\nuse the menu item <strong>File &gt; Add to Dock<\/strong>.<\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--u0q7vo9587s.png\" alt=\"Adding an app via the Share icon.\" \/><\/p>\n<p><em>Adding an app via the <strong>Share<\/strong> icon.<\/em><\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--9zgyksdtzr.png\" alt=\"Adding an app via the File menu.\" \/><\/p>\n<p><em>Adding an app via the <strong>File<\/strong> menu.<\/em><\/p>\n<p>You can adjust the name and icon if desired. The URL is the URL you're on for\npages without a manifest, or the <code>start_url<\/code> for pages with a manifest. It can't\nbe changed. For pages without an icon, Safari will create a fallback icon based on the first letter of the page's title.<\/p>\n<p><strong>\ud83d\udc40 Observation:<\/strong> Unlike on iOS\/iPadOS, you can't add the same app twice,\nunless you rename it.<\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--jbz4jqyyylc.png\" alt=\"App name and icon are adjustable, the URL is not.\" \/><\/p>\n<p><em>App name and icon are adjustable, the URL is not.<\/em><\/p>\n<p>The web app icon then appears in your Dock. Maskable icons are supported, and\nthe typical macOS squircle shape is respected. Closing all windows of an app\nleaves the app running, aligned with macOS UX paradigms.<\/p>\n<p><strong>\ud83d\udc40 Observation:<\/strong> Unlike on Chrome, the app doesn't launch immediately and\n&quot;morph&quot; from in-tab to in-app, but instead you remain on the tab and need to\nlaunch the app manually.<\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--1iikfvhhzcr.png\" alt=\"Web app added to the Dock.\" \/><\/p>\n<p><em>Web app added to the Dock.<\/em><\/p>\n<p>When right-clicking the Dock icon, you can uncheck <strong>Keep in Dock<\/strong> and still launch the app via Launchpad, Spotlight Search, or even just by double-clicking the app icon in <code>~\/Applications\/<\/code>.<\/p>\n<h2 id=\"launch-experience\" tabindex=\"-1\">Launch experience <a class=\"direct-link\" href=\"https:\/\/blog.tomayac.com\/2023\/06\/07\/web-apps-on-macos-sonoma-14-beta\/#launch-experience\" aria-hidden=\"true\">\ud83d\udd17<\/a><\/h2>\n<p>The out-of-the box launch experience of web apps is fantastic. Nowhere does it\ngive away that this is a web app. For apps with a manifest, there's no Safari UI\nwhatsoever, and the expectation is that such apps are single-page apps that\nprovide their own navigation controls. If an app is well made, lay persons\nprobably wouldn't be able to tell that something is a web app.<\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--hysefdcnykc.png\" alt=\"Web app running without any Safari UI.\" \/><\/p>\n<p><em>Web app running without any Safari UI.<\/em><\/p>\n<p><strong>\ud83d\udc40 Observation:<\/strong> Different from iOS\/iPadOS, credentials in cookies are copied\nover, so if you were logged in when running in the tab, you're logged in when\nyou launch the app. No other storage means apart from cookies are copied. <em>&quot;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&quot;.<\/em><\/p>\n<p><strong>\ud83d\udc40 Observation:<\/strong> Web Inspector (DevTools) is blocked, even with the <strong>Show features for web developers<\/strong> checkbox checked. There's no <strong>Develop<\/strong> menu item nor can you right-click and <strong>Inspect Element<\/strong>. This looks like a conscious decision.<\/p>\n<p><strong>\ud83d\udc40 Observation:<\/strong> Extensions don't run and likewise aren't displayed. Also\nprobably a conscious decision.<\/p>\n<p><strong>\ud83d\udc40 Observation:<\/strong> Same-origin (in-scope) links are handled in-app, cross-origin (out-of-scope) links open in the default browser. A notable exception are OAuth flow links, which are handled in-app based on a heuristic.<\/p>\n<p>If a user navigates to an already installed app\nin Safari, a prompt is displayed that invites the user to <strong>Open in web app<\/strong>.<\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--k85cr23x5v.png\" alt=\"Prompt inviting the user to Open in web app.\" \/><\/p>\n<p><em>Prompt inviting the user to <strong>Open in web app<\/strong>.<\/em><\/p>\n<h2 id=\"macos-integration-experience\" tabindex=\"-1\">macOS integration experience <a class=\"direct-link\" href=\"https:\/\/blog.tomayac.com\/2023\/06\/07\/web-apps-on-macos-sonoma-14-beta\/#macos-integration-experience\" aria-hidden=\"true\">\ud83d\udd17<\/a><\/h2>\n<p>Web apps on Mac let you focus on the websites you use all the time, separate\nfrom the rest of your browsing. Like all Mac apps, web apps work great with\nStage Manager, Mission Control, and keyboard shortcuts like Command + Tab. Web\napps can be opened from the Dock, Launchpad, and Spotlight Search.<\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--6e18tk2ywgl.png\" alt=\"Multitasking experience.\" \/><\/p>\n<p><em>Multitasking experience.<\/em><\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--gyygf94lo0l.png\" alt=\"Spotlight search experience.\" \/><\/p>\n<p><em>Spotlight search experience.<\/em><\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--cwy5ftpy4qi.png\" alt=\"Launchpad experience.\" \/><\/p>\n<p><em>Launchpad experience.<\/em><\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--wg589k8r7mh.png\" alt=\"Stage Manager experience.\" \/><\/p>\n<p><em>Stage Manager experience.<\/em><\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--n1elzn6cq9n.png\" alt=\"All web apps have an About dialog.\" \/><\/p>\n<p><em>All web apps have an <strong>About<\/strong> dialog.<\/em><\/p>\n<h2 id=\"settings-and-permissions\" tabindex=\"-1\">Settings and permissions <a class=\"direct-link\" href=\"https:\/\/blog.tomayac.com\/2023\/06\/07\/web-apps-on-macos-sonoma-14-beta\/#settings-and-permissions\" aria-hidden=\"true\">\ud83d\udd17<\/a><\/h2>\n<p>Web apps work with AutoFill credentials from iCloud Keychain and from\nthird-party apps that have adopted the\n<a href=\"https:\/\/developer.apple.com\/documentation\/bundleresources\/entitlements\/com_apple_developer_authentication-services_autofill-credential-provider\">Credential Provider Extension API<\/a>.\nUsers can grant permission to a web app to use their camera, microphone and\nlocation in the same way they grant such permissions to other Mac apps through\nsystem prompts and the Privacy &amp; Security section of System Settings.<\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--2rirguybc3w.png\" alt=\"System settings with Camera permissions.\" \/><\/p>\n<p><em>System settings with Camera permissions.<\/em><\/p>\n<p>Web apps on Mac support\n<a href=\"https:\/\/developer.apple.com\/documentation\/usernotifications\/sending_web_push_notifications_in_web_apps_safari_and_other_browsers?language=objc\">web push<\/a>,\n<a href=\"https:\/\/webkit.org\/blog\/14112\/badging-for-home-screen-web-apps\/\">badging<\/a>, and\nall the usual web standards implemented by WebKit, just like web apps\n<a href=\"https:\/\/webkit.org\/blog\/13878\/web-push-for-web-apps-on-ios-and-ipados\/\">on iOS and iPadOS<\/a>.<\/p>\n<p><strong>\ud83d\udc40 Observation:<\/strong> There seems to be a <a href=\"https:\/\/bugs.webkit.org\/show_bug.cgi?id=257807\">bug<\/a> where the hosting Web App appears as\nthe app requesting the Notifications permission. Notifications then work as\nexpected, though, including using the correct icon.<\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--f4adwfi8t1.png\" alt=\"Notifications permission prompt with the wrong app name and icon.\" \/><\/p>\n<p><em>Notifications permission prompt with the wrong app name and icon.<\/em><\/p>\n<p>Web apps have their own <strong>Settings<\/strong> dialog. In <strong>General<\/strong>, the app name and\nicon can be changed and navigation controls can be toggled on or off. The\n<a href=\"https:\/\/developer.apple.com\/documentation\/safari-release-notes\/safari-15-release-notes#:~:text=Added%20support%20for%20the%20theme-color%20meta%20tag%20to%20change%20the%20tab%20bar%20background%20and%20over-scroll%20area%20in%20macOS%20and%20iPadOS%2C%20and%20the%20status%20bar%20in%20iOS.\">theming behavior of the title bar<\/a>\ncan be changed, too.<\/p>\n<p><strong>\ud83d\udc40 Observation:<\/strong> Navigation controls are toggled off when there's a manifest\nwith <code>&quot;display&quot;: &quot;standalone&quot;<\/code>. In all other cases, even if a manifest exists\nbut with a different <code>&quot;display&quot;<\/code> mode,<\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--kgsu98ksrqf.png\" alt=\"Web app Settings dialog on the General tab.\" \/>\n<em>Web app <strong>Settings<\/strong> dialog on the <strong>General<\/strong> tab.<\/em><\/p>\n<p><strong>\ud83d\udc40 Observation:<\/strong> There's currently a <a href=\"https:\/\/bugs.webkit.org\/show_bug.cgi?id=257806\">bug<\/a> where web apps don't correctly report <code>matchMedia('(display-mode: standalone)')<\/code>. Added to the Dock web apps think they run in a tab.<\/p>\n<p>With navigation controls enabled, there's an <strong>Open in Safari<\/strong> icon in the\nupper right corner. Despite its label, it actually respects the user's default\nbrowser.<\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--c95fwgkg6e9.png\" alt=\"Open in Safari icon.\" \/><\/p>\n<p><em><strong>Open in Safari<\/strong> icon.<\/em><\/p>\n<p>Web pages get navigation affordances in the form of a back and forward button.\nThere's no reload button.<\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--f5jaczcwma.png\" alt=\"Back and forward buttons.\" \/><\/p>\n<p><em>Back and forward buttons.<\/em><\/p>\n<p><strong>\ud83d\udc40 Observation:<\/strong> With navigation controls toggled to off, the title of the\nweb app sourced from the manifest is not shown. With navigation controls toggled\nto on, the title sourced from the <code>&lt;title&gt;<\/code> is shown.<\/p>\n<p><strong>\ud83d\udc40 Observation:<\/strong> When you right-click, there's a context menu with <strong>Reload<\/strong> or <strong>Back<\/strong> and <strong>Reload<\/strong>. This works independent from whether navigation controls are toggled on or off.<\/p>\n<p>The <strong>Privacy<\/strong> tab allows the user to clear website data and links into the\n<strong>Privacy &amp; Security Settings<\/strong> of the System Settings app.<\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--f37x3wpvl5.png\" alt=\"Web app Settings dialog on the Privacy tab.\" \/><\/p>\n<p><em>Web app <strong>Settings<\/strong> dialog on the <strong>Privacy<\/strong> tab.<\/em><\/p>\n<h2 id=\"technical-analysis\" tabindex=\"-1\">Technical analysis <a class=\"direct-link\" href=\"https:\/\/blog.tomayac.com\/2023\/06\/07\/web-apps-on-macos-sonoma-14-beta\/#technical-analysis\" aria-hidden=\"true\">\ud83d\udd17<\/a><\/h2>\n<p>(See <a href=\"https:\/\/bugs.chromium.org\/p\/chromium\/issues\/detail?id=1451667#c7\">comment #7 of Chromium bug 1451667<\/a> for the full details.)<\/p>\n<p>All apps are stored in <code>~\/Applications\/<\/code>. The package contents of each apps are:<\/p>\n<ul>\n<li>a <code>_CodeSignature<\/code> folder with code signature metadata<\/li>\n<li>a <code>Resources<\/code> folder with just the app icons as a single\n<code>ApplicationIcon.icns<\/code> file<\/li>\n<li>an <code>Info.plist<\/code> file.<\/li>\n<\/ul>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--oekactyqlf.png\" alt=\"The package contents of an app.\" \/><\/p>\n<p><em>The package contents of an app.<\/em><\/p>\n<p>The <code>Info.plist<\/code> file interestingly contains an XML version of key parts of the\nmanifest and metadata about the app.<\/p>\n<pre class=\"language-xml\"><code class=\"language-xml\"><span class=\"token prolog\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?><\/span>\n<span class=\"token doctype\"><span class=\"token punctuation\">&lt;!<\/span><span class=\"token doctype-tag\">DOCTYPE<\/span> <span class=\"token name\">plist<\/span> <span class=\"token name\">PUBLIC<\/span> <span class=\"token string\">\"-\/\/Apple\/\/DTD PLIST 1.0\/\/EN\"<\/span> <span class=\"token string\">\"http:\/\/www.apple.com\/DTDs\/PropertyList-1.0.dtd\"<\/span><span class=\"token punctuation\">><\/span><\/span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>plist<\/span> <span class=\"token attr-name\">version<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=<\/span><span class=\"token punctuation\">\"<\/span>1.0<span class=\"token punctuation\">\"<\/span><\/span><span class=\"token punctuation\">><\/span><\/span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dict<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>CFBundleIconFile<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>ApplicationIcon<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>CFBundleIdentifier<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span>\n      <span class=\"token punctuation\">><\/span><\/span>com.apple.Safari.WebApp.svgco.de.53298B34-AF7F-4074-9CA9-1EE46B7E3E83<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span>\n    <span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>CFBundleInfoDictionaryVersion<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>6.0<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>CFBundleName<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>SVGcode<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>CFBundlePackageType<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>AAPL<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>CFBundleShortVersionString<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>1.0<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>CFBundleSupportedPlatforms<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>array<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>MacOSX<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>array<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>CFBundleURLTypes<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>array<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dict<\/span><span class=\"token punctuation\">><\/span><\/span>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>CFBundleURLSchemes<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>array<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>x-webkit-app-launch<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>array<\/span><span class=\"token punctuation\">><\/span><\/span>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>LSHandlerRank<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>None<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dict<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>array<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>CFBundleVersion<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>1<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>LSMinimumSystemVersion<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>14.0<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>LSTemplateApplication<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>true<\/span> <span class=\"token punctuation\">\/><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>LSTemplateApplicationParameters<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dict<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>CFBundleIdentifier<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>com.apple.Safari.WebApp<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>TemplateAppUUID<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>53298B34-AF7F-4074-9CA9-1EE46B7E3E83<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>defaultarguments<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>true<\/span> <span class=\"token punctuation\">\/><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>teamIdentifier<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dict<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>Manifest<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dict<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>description<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span>\n        <span class=\"token punctuation\">><\/span><\/span>SVGcode is a Progressive Web App that lets you convert raster images\n        like JPG, PNG, GIF, WebP, AVIF, etc. to vector graphics in SVG\n        format.<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span>\n      <span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>display<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>standalone<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>icons<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>array<\/span><span class=\"token punctuation\">><\/span><\/span>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dict<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>purpose<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>maskable<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>sizes<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>1024x1024<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>src<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>https:\/\/svgco.de\/favicon.png<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>type<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>image\/png<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dict<\/span><span class=\"token punctuation\">><\/span><\/span>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dict<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>purpose<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>any<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>sizes<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>150x150<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>src<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>https:\/\/svgco.de\/favicon.svg<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>type<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>image\/svg+xml<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dict<\/span><span class=\"token punctuation\">><\/span><\/span>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dict<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>purpose<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>monochrome<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>sizes<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>150x150<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>src<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>https:\/\/svgco.de\/favicon-bw.svg<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>type<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>image\/svg+xml<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dict<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>array<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>name<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>SVGcode<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>scope<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>https:\/\/svgco.de<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>short_name<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>SVGcode<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>start_url<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>https:\/\/svgco.de\/<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>theme_color<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>#ffffff<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dict<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>WKPushBundleMetadata<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>dict<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>manifestId<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>key<\/span><span class=\"token punctuation\">><\/span><\/span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>https:\/\/svgco.de\/<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>string<\/span><span class=\"token punctuation\">><\/span><\/span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dict<\/span><span class=\"token punctuation\">><\/span><\/span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>dict<\/span><span class=\"token punctuation\">><\/span><\/span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>plist<\/span><span class=\"token punctuation\">><\/span><\/span><\/code><\/pre>\n<p>Similar to iOS\/iPadOS, web apps run in the context of a separate process called\n<code>Web App.app<\/code>, which resides in\n<code>\/System\/Volumes\/Preboot\/Cryptexes\/App\/System\/Library\/CoreServices\/Web App.app<\/code>.<\/p>\n<p><strong>\ud83d\udc40 Observation:<\/strong> Separating Safari and Web App allows both to run\nindependently. You can open a Web app without opening Safari, you can close\nSafari without all web apps closing.<\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--3cd4wjo74qu.png\" alt=\"The Web App.app app in Finder.\" \/><\/p>\n<p><em>The <code>Web App.app<\/code> app in Finder.<\/em><\/p>\n<p>Each web app runs as its own process of kind <code>Web<\/code>, accompanied by a number of\nhelper processes of kind <code>Apple<\/code>. They can all be seen in Activity Monitor.<\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--cln1h5jyf1.png\" alt=\"Activity Monitor showing all processes associated with a web app.\" \/><\/p>\n<p><em>Activity Monitor showing all processes associated with a web app.<\/em><\/p>\n<h2 id=\"wish-list-for-apple\" tabindex=\"-1\">Wish list for Apple <a class=\"direct-link\" href=\"https:\/\/blog.tomayac.com\/2023\/06\/07\/web-apps-on-macos-sonoma-14-beta\/#wish-list-for-apple\" aria-hidden=\"true\">\ud83d\udd17<\/a><\/h2>\n<p>(Also see <a href=\"https:\/\/docs.google.com\/document\/d\/1chkEulpKBNQQfGIgTfQSbJhjw5mtZhvE47PF4tyTEXc\/edit#\">Most wanted PWA features on iOS\/iPadOS\/macOS Safari<\/a>.)<\/p>\n<ul>\n<li>Add support for the\n<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/File_System_Access_API\">File System Access API<\/a>,\nso users can install apps and edit files directly, rather than opening them\nand then downloading a copy.\n[<a href=\"https:\/\/bugs.webkit.org\/show_bug.cgi?id=231706\">\ud83e\udded\u00a0231706<\/a>]<\/li>\n<li>Add support for\n<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/DataTransferItem\/getAsFileSystemHandle\"><code>DataTransferItem.getAsFileSystemHandle()<\/code><\/a>,\nso users can drag and drop files into web apps and edit the file.\n[<a href=\"https:\/\/bugs.webkit.org\/show_bug.cgi?id=257792\">\ud83e\udded 257792<\/a>]<\/li>\n<li>Add support for the\n<a href=\"https:\/\/developer.chrome.com\/articles\/web-share-target\/\">Web Share Target API<\/a>,\nso you can share data to installed web apps.\n[<a href=\"https:\/\/bugs.webkit.org\/show_bug.cgi?id=194593\">\ud83e\udded\u00a0194593<\/a>]<\/li>\n<li>Let web apps programmatically trigger the <strong>Add to Dock<\/strong> flow, since the\n<strong>Share<\/strong> icon and the <strong>File<\/strong> menu install ways are hard to discover.\n[<a href=\"https:\/\/bugs.webkit.org\/show_bug.cgi?id=255716\">\ud83e\udded\u00a0255716<\/a>]<\/li>\n<li>Add support for the\n<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Window_Controls_Overlay_API\">Window Controls Overlay API<\/a>,\nso the gorgeous current experience can be made even more gorgeous.\n[<a href=\"https:\/\/bugs.webkit.org\/show_bug.cgi?id=257782\">\ud83e\udded\u00a0257782<\/a>]<\/li>\n<\/ul>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--4dq3oazo75q.png\" alt=\"Spotify native app title bar experience.\" \/><\/p>\n<p><em>Spotify native app title bar experience.<\/em><\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--9bwtu16pbtv.png\" alt=\"Spotify web app title bar experience.\" \/><\/p>\n<p><em>Spotify web app title bar experience.<\/em><\/p>\n<ul>\n<li>Add support for the\n<a href=\"https:\/\/github.com\/WICG\/file-handling\/blob\/main\/explainer.md\">File Handling API<\/a>,\nso web apps can open files from Finder by double click if the web app is\nregistered as the default file handler for a given file type, or by right\nclick and then <strong>Open with<\/strong> if the web app can handle a file type, but isn't\nthe default file handler.\n[<a href=\"https:\/\/bugs.webkit.org\/show_bug.cgi?id=257783\">\ud83e\udded\u00a0257783<\/a>]<\/li>\n<li>Add support for the\n<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Launch_Handler_API\">Launch Handler API<\/a>,\nso web apps can decide how they want to handle launch events.\n[<a href=\"https:\/\/bugs.webkit.org\/show_bug.cgi?id=257785\">\ud83e\udded 257785<\/a>]<\/li>\n<li>Reflect the cookie-copying logic on iOS\/iPadOS. It's a very frustrating\nexperience if you have to log in twice, even more so if two-factor\nauthentication is involved.\n[<a href=\"https:\/\/bugs.webkit.org\/show_bug.cgi?id=257786\">\ud83e\udded 257786<\/a>]<\/li>\n<li>Allow users to turn off the <strong>Open in web app<\/strong> prompt.<\/li>\n<\/ul>\n<h2 id=\"recommendations-for-chrome\" tabindex=\"-1\">Recommendations for Chrome <a class=\"direct-link\" href=\"https:\/\/blog.tomayac.com\/2023\/06\/07\/web-apps-on-macos-sonoma-14-beta\/#recommendations-for-chrome\" aria-hidden=\"true\">\ud83d\udd17<\/a><\/h2>\n<ul>\n<li>Better respect macOS' design paradigms. Currently web app icon handling looks\nnot integrated and icon shapes are all over the place. The examples below are\nall web apps installed via Chrome.<\/li>\n<\/ul>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--pp6i6yqgm9l.png\" alt=\"Web app icon shapes installed from Chrome don't respect the squircle.\" \/><\/p>\n<p><em>Web app icon shapes installed from Chrome don't respect the squircle.<\/em><\/p>\n<ul>\n<li>Move the extension puzzle piece and the Window Controls Overlay chevron into\nthe three dots menu. Web apps can look so much cleaner without both in plain\nsight.<\/li>\n<\/ul>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--gqdtdnumc98.png\" alt=\"Window Controls Overlay chevron and extension puzzle piece clutter the UI of\nChrome-installed apps.\" \/><\/p>\n<p><em>Window Controls Overlay chevron and extension puzzle piece clutter the UI of\nChrome-installed apps.<\/em><\/p>\n<h2 id=\"new-fugu-api-needs\" tabindex=\"-1\">New Fugu API needs <a class=\"direct-link\" href=\"https:\/\/blog.tomayac.com\/2023\/06\/07\/web-apps-on-macos-sonoma-14-beta\/#new-fugu-api-needs\" aria-hidden=\"true\">\ud83d\udd17<\/a><\/h2>\n<p>With Chrome and Safari now allowing web apps to be installed on macOS, it would\nbe fantastic if installed apps could respect macOS UX guidelines and populate\nthe system-level menu. Ideally Apple and Google engage jointly on the\ncorresponding Project Fugu \ud83d\udc21 API request tracked in\n<a href=\"https:\/\/crbug.com\/1295253\">crbug\/1295253<\/a>.<\/p>\n<p><img src=\"https:\/\/blog.tomayac.com\/images\/webappsonmacos--gg6jy7x6mg.png\" alt=\"Web app default menu.\" \/><\/p>\n<p><em>Web app default menu.<\/em><\/p>\n<h2 id=\"conclusion\" tabindex=\"-1\">Conclusion <a class=\"direct-link\" href=\"https:\/\/blog.tomayac.com\/2023\/06\/07\/web-apps-on-macos-sonoma-14-beta\/#conclusion\" aria-hidden=\"true\">\ud83d\udd17<\/a><\/h2>\n<p>Web apps in macOS Sonoma 14 Beta seamlessly integrate into the macOS experience,\nwith no or very little visible Safari UI and with support for various operating\nsystem features. There is an enormous potential for web apps on macOS to\nsucceed, and if Apple only works on a third of the items on my wish list, the\npotential is even bigger.<\/p>\n<h2 id=\"related-links\" tabindex=\"-1\">Related links <a class=\"direct-link\" href=\"https:\/\/blog.tomayac.com\/2023\/06\/07\/web-apps-on-macos-sonoma-14-beta\/#related-links\" aria-hidden=\"true\">\ud83d\udd17<\/a><\/h2>\n<ul>\n<li><a href=\"https:\/\/webkit.org\/blog\/14205\/news-from-wwdc23-webkit-features-in-safari-17-beta\/#web-apps\">News from WWDC23: WebKit Features in Safari 17 beta<\/a><\/li>\n<li><a href=\"https:\/\/developer.apple.com\/videos\/play\/wwdc2023\/10120\/\">What's new in web apps<\/a><\/li>\n<\/ul>\n\n\t\t\t<p>\n\t\t\t\t<img alt=\"Thomas Steiner\" width=\"32\" height=\"32\" src=\"https:\/\/blog.tomayac.com\/feed.php?dl=https%3A%2F%2Fblog.tomayac.com%2F2023%2F06%2F07%2Fweb-apps-on-macos-sonoma-14-beta%2F&dp=%2F2023%2F06%2F07%2Fweb-apps-on-macos-sonoma-14-beta%2F&dt=Web%20Apps%20on%20macOS%20Sonoma%2014%20Beta\" alt=\"\">\n\t\t\t\t<br\/>This post appeared first on <a href=\"https:\/\/blog.tomayac.com\/2023\/06\/07\/web-apps-on-macos-sonoma-14-beta\/\">https:\/\/blog.tomayac.com\/2023\/06\/07\/web-apps-on-macos-sonoma-14-beta\/<\/a>.\n\t\t\t<\/p>\n\t\t","protected":false},"excerpt":{"rendered":"<p>\t\t\tExecutive summary \ud83d\udd17<br \/>\nWith macOS Sonoma, Apple goes all-in on the concept of installable web apps.<br \/>\nThey&#8217;re highly integrated in the overall macOS experience and don&#8217;t give away<br \/>\ntheir web roots by not showing any Safari UI at all.<br \/>\nTesting environment &#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"intlwemo_wallet_address":"","footnotes":""},"categories":[],"tags":[],"class_list":["post-3484","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/tomayac.com\/wordpress\/wp-json\/wp\/v2\/posts\/3484","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tomayac.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tomayac.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tomayac.com\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tomayac.com\/wordpress\/wp-json\/wp\/v2\/comments?post=3484"}],"version-history":[{"count":4,"href":"https:\/\/tomayac.com\/wordpress\/wp-json\/wp\/v2\/posts\/3484\/revisions"}],"predecessor-version":[{"id":3489,"href":"https:\/\/tomayac.com\/wordpress\/wp-json\/wp\/v2\/posts\/3484\/revisions\/3489"}],"wp:attachment":[{"href":"https:\/\/tomayac.com\/wordpress\/wp-json\/wp\/v2\/media?parent=3484"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tomayac.com\/wordpress\/wp-json\/wp\/v2\/categories?post=3484"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tomayac.com\/wordpress\/wp-json\/wp\/v2\/tags?post=3484"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}