I'm having some troubles with an iOS Smart App Banner, which I'm trying to add through JavaScript.
The actual smartbanner is as simple as adding this little block to the head of the HTML:
<meta name="apple-itunes-app" content="app-id=375380948">
Unfortunately, I'm quite restricted in the way I can upload my script. I can't change the HTML directly, so I'll do it through our Tag Manager, which basically does it through JavaScript. But it turns out that this doesn't work.
I've tried to simplify the case for testing:
Hardcoded tag in the HTML: works (as expected)
<meta name="apple-itunes-app" content="app-id=375380948">
Inserted with JavaScript directly when the document is ready: works
$(document).ready(function(){ $("head").append('<meta name="apple-itunes-app" content="app-id=375380948">'); });
Inserted with JavaScript, after a
setTimeout
delay: DOES NOT WORK$(document).ready(function(){ setTimeout(showBanner, 1); //after 1 millisecond }); function showBanner(){ $("head").append('<meta name="apple-itunes-app" content="app-id=375380948">'); }
Can anyone confirm or explain why this delayed JavaScript doesn't work?
Important: for testing open the page on an actual iOS device! Desktop Safari/Chrome or iOS emulator won't work. Also, don't close the banner, because it won't show up a second time.
UPDATE:
I've added some examples without jQuery, so plain 'ol JavaScript. But the results are the same. As soon as we wait for a setTimeout()
the Smart App Banner fails to load.
Vanilla JavaScript - direct execution. works
showBanner(); function showBanner() { var meta = document.createElement("meta"); meta.name = "apple-itunes-app"; meta.content = "app-id=375380948"; document.head.appendChild(meta); }
Vanilla JavaScript - delayed execution. DOES NOT WORK
setTimeout(showBanner, 1); function showBanner() { var meta = document.createElement("meta"); meta.name = "apple-itunes-app"; meta.content = "app-id=375380948"; document.head.appendChild(meta); }
UPDATE 2:
The exact same unfortunate behavior can be observed when loading the script asynchronously
async loading. DOES NOT WORK
<script src="async.js" async></script>
Which then calls the same vanilla JavaScript with direct execution showBanner();
function showBanner() { var meta = document.createElement("meta"); meta.name = "apple-itunes-app"; meta.content = "app-id=375380948"; document.head.appendChild(meta); }
CONCLUSION:
I can only conclude that iOS Safari only looks for the smartbanner the HTML in the primary thread. And that makes me sad :-(
Only the directly available HTML, or HTML that is added synchronously through JavaScript.
But no a-sync action is allowed, be it loading the JavaScript asynchronously, or using setTimeout()
(or an other construct that uses eval()
)
app-id
in your examples is stale? Your "Vanilla JavaScript - direct execution." looks like exactly what I need. However, when testing on an iPhone 12 I saw the banner flash blank momentarily in Safari and nothing in Chrome (which is really just Safari under the hood on iOS I've learned). Anyway, if possible maybe you can update to some point to some app unlikely to be removed? – Tiny