Starcounter / Home

Starcounter is an in-memory database application engine.
https://starcounter.io
27 stars 1 forks source link

Create a dynamic manifest.json URL in app-shell HTML #352

Closed alshakero closed 6 years ago

alshakero commented 6 years ago

It makes sense to serve manifest.json in our apps. It's the first condition to make PWAs (progress web apps).

But, adding a static <link rel="manifest" href="/manifest.json"> won't work since it would cover all running apps. And each app neads its own manifest.json.

The only solution I could think of is to create a third parameter in the app-shell template. ({0} is title , {1} is session id, {2} can be /app-name/manifest.json. And people can put their own manifest.json in wwwroot of their apps.

This is a request from AdFenix. And an important need for PWAs.

// cc @warpech @tomalec @mmnosek @atifwaqar

mmnosek commented 6 years ago

I'm not sure what do you mean by "parameter in the app-shell template", but I think that defining manifest on the SC application level is a bad idea. Having 20 apps running, how are we going to determine what entry is more important than another one?

alshakero commented 6 years ago

I'm not sure what do you mean by "parameter in the app-shell template

I mean just like we do title, see {0}, I think we need a third parameter {2} that says <app-name>/manifest.js. https://github.com/Starcounter/level1/blob/develop/src/BuildSystem/ClientFiles/StaticFiles/sys/app-shell/app-shell.html#L6

how are we going to determine what entry is more important than another one?

Just like we determine the app title of each of those 20 apps.

warpech commented 6 years ago

app-shell.html must not include any parameters or other customizations, because app-shell.html is only an entry point to the whole solution of apps. It must be seen as the minimum part that is cacheable and non-changeable. It is like BIOS in your PC. The BIOS does not dictate how does the icon for Microsoft Word look like.

The correct layer to set <link rel="manifest" href="/manifest.json"> is in a surface, because a surface is a dynamic view that you can morph into or morph out from.

alshakero commented 6 years ago

I understand that and I remember the discussion regarding the session ID. but I thought since we're doing title and session ID for the mean time, throwing the app-name/manifest.json shouldn't be bad.

The correct layer to set is in a surface, because a surface is a dynamic view that you can morph into or morph out from.

TBH, I don't know yet what is a surface, I assume it's like MasterPage in KitchenSink. It's worth mentioning that manifest.json doesn't work if injected dynamically like viewport meta tags do. I experimented on it last week and sadly it's not possible. Chrome simply ignores the tag.

atifwaqar commented 6 years ago

I have verified @alshakero's experiment on my Chatbot app. and it does not work. So temporarily I added the manifest import in app-shell.html

warpech commented 6 years ago

TBH, I don't know yet what is a surface, I assume it's like MasterPage in KitchenSink.

A surface is totally unlike MasterPage:


It's worth mentioning that manifest.json doesn't work if injected dynamically like viewport meta tags do. I experimented on it last week and sadly it's not possible. Chrome simply ignores the tag.

Then we have a problem. So Chrome wants us to reboot the app shell when morphing from one view to another if we want that view to be "installable"? This is ridiculous, isn't it.

Maybe it is possible to add an empty <link rel="manifest" href=""> and then modify the href value dynamically?

In Anrdoid, I can put a shortcut to Google Maps native app on my home screen and I can also put a shortcut to a search result in that app on my home screen. I suspect this should also be possible with PWA. If not, then this is a shortcoming of Chrome.

I can see more people have questions about it:

alshakero commented 6 years ago

Maybe it is possible to add an empty <link rel="manifest" href=""> and then modify the href value dynamically?

G.E.N.I.U.S!

Works like a charm! http://plnkr.co/edit/KYa578reWKOnOjtpmjvg?p=preview

atifwaqar commented 6 years ago

@warpech as @alshakero said G.E.N.I.U.S! ... you really are one :)

Thanks guys for the help.

alshakero commented 6 years ago

This means we still need to add an HTML tag with empty href. Right? @warpech


Meanwhile @Mackiovello maybe you would like to document this?

A very raw suggesion to save you time:

Defining manifest.json for your app

Since all Starcounter apps start off from the same app-shell HTML, it is not possible to define manifest.json in that HTML, for it represents more than one application.

And injecting a <link rel="manifest" href="manifest.json"> from your app's Javascript will be ignored by Chrome and Firefox. However, browsers seem to notice dynamic changes to a tag that is already there. That's why Starcounter app-shell HTML has an a manifest link tag with the id manifest-placeholder that you can find and update its href attribute to point to your manifest.json this is tested and it works.

Example

Say, your manifest is called my-app-manifest.json.

You need to put this Javascript in your home page:

document.querySelector('#manifest-placeholder').href = 'my-app-manifest.json';

And your my-app-manifest.json will be used.

Mackiovello commented 6 years ago

Thank you for the documentation @alshakero!

One question: you say that "Starcounter app-shell HTML has an a manifest link tag with the id manifest-placeholder". I can't find this, has it been implemented yet. Looking in app-shell.html: https://github.com/Starcounter/level1/blob/0d4cad7d3d0fa5366eb7af0cda098234f5c8d46c/src/BuildSystem/ClientFiles/StaticFiles/sys/app-shell/app-shell.html

Edit: Just read the whole issue. I understand that it's not implemented yet. Please give me a ping when it's implemented and I'll add @alshakero's docs

alshakero commented 6 years ago

@Mackiovello sure 👍

alshakero commented 6 years ago

@warpech a gentle ping. We'll still need to create an empty tag in app-shell right?

warpech commented 6 years ago

Let's create the empty tag in app-shell.hhtml. It should not have an arbitrary id="". It is enough to use a selector:

document.querySelector('link[rel="manifest"]').href = 'my-app-manifest.json';

Since this is a customer's priority, let's add it to app-shell.html ASAP.

alshakero commented 6 years ago

PRed in https://github.com/Starcounter/level1/pull/4458 & https://github.com/Starcounter/StarcounterClientFiles/pull/25

atifwaqar commented 6 years ago

It would be great if <html lang="en"> & <meta id="theme-color" name="theme-color" content="" /> are also handled in similar way. Or if there is a better way please do suggest. Thanks :)

alshakero commented 6 years ago

Closing as done.

Regarding the other tags can you please create a seperate issue if you need them?

Mackiovello commented 6 years ago

This is not documented. Assigning myself to move https://github.com/Starcounter/Home/issues/352#issuecomment-357773623 to the docs

Mackiovello commented 6 years ago

Documentation: https://docs.starcounter.io/v/2.4/guides/web-apps/app-shell#adding-manifest.json

alshakero commented 6 years ago

That's why Starcounter app-shell HTML has an a manifest link tag with the id manifest-placeholder that you can find and update its href attribute to point to your manifest.json.

Should be:

That's why Starcounter app-shell HTML has a manifest link tag with an empty href attribute that you can populate with the URL of your manifest.json, Chrome and FF will notice this update and respect the values in your linked manifest.

Mackiovello commented 6 years ago

You're completely right, I missed that one. It's fixed now

alshakero commented 6 years ago

One more tiny issue, reported by @atifwaqar, it's worth adding:

"Please note that the Application tab in Chrome DevTools might not reflect the updates to your manifest dynamically. Meaning you'll need to re-open Chrome DevTools after you populate the manifest to see the values in it respected."

Can be rephrased better for sure.

Mackiovello commented 6 years ago

Just to make sure, do you mean "updates to your app-shell dynamically"? I thought the manifest is just a static JSON file that doesn't change.

Mackiovello commented 6 years ago

Does this make sense?

The Application tab in Chrome DevTools might not immediately reflect the dynamic changes to the app-shell. Thus, close and re-open Chrome DevTools after linking to the manifest to see the changes.

atifwaqar commented 6 years ago

Just to make sure, do you mean "updates to your app-shell dynamically"? I thought the manifest is just a static JSON file that doesn't change.

Well, there can be many manifests (depending on how many different apps are hosted on your server). So yes, it means updates to your app-shell dynamically

Does this make sense

Yes it does.

tomalec commented 6 years ago

Chrome and Firefox will notice this update and respect the values in the linked manifest.

How about other browsers? I'd suggest not to stick to specific names here.