drufball
drufball

Reputation: 71

Set start_url in web app manifest based on the URL that was added to homescreen

My site has several subsections. When a user adds the site to their homescreen, I'd like to make sure that the home screen icon launches them into the subsection they were on when they added to homescreen.

I can register a different manifest for each subsection, but this doesn't work for single page apps where there's no page reload. I'm considering storing the subsection in a cookie and then redirecting from a generic start URL based on that cookie.

Is there a better way to do this?

Upvotes: 7

Views: 9819

Answers (5)

david-l
david-l

Reputation: 623

Had the same problem and tried messing about with the start_url applying many suggestions and none worked. What did work is to remove start_url all together.

Now I'm able to go to any page under and subdirectory and save the page to my phone home screen, when clicking on the save link I taken to the correct page.

Tested this in Chrome, Safari, Firefox and Edge.

Hope that helps.

Upvotes: 0

Ricki-BumbleDev
Ricki-BumbleDev

Reputation: 2256

Had the same problem just now. Here is my solution:

I completely removed the manifest tag from the initial HTML. Instead I now put the manifest together entirely in JS with the start_url set to window.location.href. Then I add it to the head as a Base64 data URL:

const manifest = {
  name: 'My App',
  short_name: 'My App',
  display: 'standalone',
  theme_color: '#ffffff',
  background_color: '#ffffff',
  icons: [
    { src: `${window.location.origin}/path/to/icon.png`, sizes: '192x192', type: 'image/png' },
    { src: `${window.location.origin}/path/to/icon.png`, sizes: '512x512', type: 'image/png' },
    { src: `${window.location.origin}/path/to/icon.png`, sizes: '192x192', type: 'image/png', purpose: 'maskable' },
    { src: `${window.location.origin}/path/to/icon.png`, sizes: '512x512', type: 'image/png', purpose: 'maskable' }
  ],
  start_url: window.location.href
};

const link = document.createElement('link');
link.rel = 'manifest';
link.href = `data:application/json;base64,${btoa(JSON.stringify(manifest))}`;
document.head.appendChild(link);

Seems to work on both Android and iOS.

Note: Since data URLs don't have a root you cannot specify any root-relative URLs within the manifest (e.g. for icons). But it's easy to fix by prepending with window.location.origin. Also the start_url may not be relative. E.g. using just window.location.pathname doesn't work, that's why I am using window.location.href.

Note 2: If you are using a tool to autogenerate the PWA support of your app make sure this tool doesn't generate its own manifest during the build. Usually there should be a config option to disable this. For the Vite PWA Plugin I was able to configure manifest: false.

Upvotes: 1

One solution is for each page do you have a separated manifest with attribute start_url specific to each page.

Editing: in the HTML for /your_path:

<link rel="manifest" href="/path/to/your_path-manifest.json">

in the HTML for other pages:

<link rel="manifest" href="/path/to/any_other_page-manifest.json"> 

Upvotes: 0

Fawaz
Fawaz

Reputation: 3560

If you remove the start_url from the manifest.json file then it will default to the page user was browsing while adding pwa app to homescreen. ref : https://developers.google.com/web/tools/lighthouse/audits/manifest-contains-start_url

Upvotes: 4

Matt Gaunt
Matt Gaunt

Reputation: 9821

Have you tried changing the web app manifest url when the user navigates between different subsections?

document.querySelector('link[rel=manifest]').href = '/example-manifest.json';

Upvotes: 0

Related Questions