I have a firebase website hosted in Firebase hosting and built using Ionic Framework (Angular 8.2).
The web app uses a client-side rendering (default Angular 8 behavior) and does not load any web app content to the browser's HTML. This causes significant issues in our SEO, page indexing, and page ranking.
See the HTML source code below of the default landing page for example (Note the <app-root></app-root> tag):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>GAGA</title>
<base href="/" />
<meta
name="viewport"
content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<meta name="format-detection" content="telephone=no" />
<meta name="msapplication-tap-highlight" content="no" />
<!-- <meta http-equiv="Content-Security-Policy"
content="default-src *; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'; media-src *; img-src * filesystem: data:" /> -->
<link rel="icon" type="image/png" href="assets/icon/favicon.png" />
<!-- add to homescreen for ios -->
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="theme-color" content="#1976d2" />
<meta name="mobile-web-app-capable" content="yes">
<!-- <link rel="manifest" href="manifest.webmanifest" /> -->
<link rel="apple-touch-startup-image" href="assets/splash/apple-splash-2048-2732.png" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" />
<link rel="apple-touch-startup-image" href="assets/splash/apple-splash-2732-2048.png" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" />
<link rel="apple-touch-startup-image" href="assets/splash/apple-splash-1668-2388.png" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" />
<link rel="apple-touch-startup-image" href="assets/splash/apple-splash-2388-1668.png" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" />
<link rel="apple-touch-startup-image" href="assets/splash/apple-splash-1668-2224.png" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" />
<link rel="apple-touch-startup-image" href="assets/splash/apple-splash-2224-1668.png" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" />
<link rel="apple-touch-startup-image" href="assets/splash/apple-splash-1536-2048.png" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" />
<link rel="apple-touch-startup-image" href="assets/splash/apple-splash-2048-1536.png" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" />
<link rel="apple-touch-startup-image" href="assets/splash/apple-splash-1242-2688.png" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" />
<link rel="apple-touch-startup-image" href="assets/splash/apple-splash-2688-1242.png" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" />
<link rel="apple-touch-startup-image" href="assets/splash/apple-splash-1125-2436.png" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" />
<link rel="apple-touch-startup-image" href="assets/splash/apple-splash-2436-1125.png" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" />
<link rel="apple-touch-startup-image" href="assets/splash/apple-splash-828-1792.png" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" />
<link rel="apple-touch-startup-image" href="assets/splash/apple-splash-1792-828.png" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" />
<link rel="apple-touch-startup-image" href="assets/splash/apple-splash-1242-2208.png" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" />
<link rel="apple-touch-startup-image" href="assets/splash/apple-splash-2208-1242.png" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" />
<link rel="apple-touch-startup-image" href="assets/splash/apple-splash-750-1334.png" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" />
<link rel="apple-touch-startup-image" href="assets/splash/apple-splash-1334-750.png" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" />
<link rel="apple-touch-startup-image" href="assets/splash/apple-splash-640-1136.png" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" />
<link rel="apple-touch-startup-image" href="assets/splash/apple-splash-1136-640.png" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" />
<link rel="apple-touch-icon" sizes="180x180" href="assets/icons/apple-icon-180.png" />
<link rel="apple-touch-icon" sizes="167x167" href="assets/icons/apple-icon-167.png" />
<link rel="apple-touch-icon" sizes="152x152" href="assets/icons/apple-icon-152.png" />
<link rel="apple-touch-icon" sizes="120x120" href="assets/icons/apple-icon-120.png" />
<!-- Tamara -->
<script async src="https://cdn.tamara.co/widget/tamara-widget.min.js"></script>
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-159202064-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'UA-159202064-1');
</script>
<script async src="https://www.googletagmanager.com/gtag/js?id=AW-604302093"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'AW-604302093');
</script>
<link rel="stylesheet" href="styles.eb3052c834c7da8f09b2.css"></head>
<body>
<app-root></app-root>
<noscript>Please enable JavaScript to continue using this application.</noscript>
<!-- Face Pixel Code -->
<script>
!(function (f, b, e, v, n, t, s) {
if (f.fbq) return;
n = f.fbq = function () {
n.callMethod ? n.callMethod.apply(n, arguments) : n.queue.push(arguments);
};
if (!f._fbq) f._fbq = n;
n.push = n;
n.loaded = !0;
n.version = '2.0';
n.queue = [];
t = b.createElement(e);
t.async = !0;
t.src = v;
s = b.getElementsByTagName(e)[0];
s.parentNode.insertBefore(t, s);
})(window, document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');
function logEventFb(event, obj) {
fbq('track', event, obj);
}
function initFacebookPixel(pixelId) {
fbq('init', pixelId);
}
function setPageViewFb(pageView) {
fbq('track', pageView);
console.log('track view:', pageView);
}
function shareViaSocial(text) {
navigator.share({
text
});
}
</script>
<!-- Snap Pixel Code -->
<script type="text/javascript">
(function (e, t, n) {
if (e.snaptr) return;
var a = (e.snaptr = function () {
a.handleRequest ? a.handleRequest.apply(a, arguments) : a.queue.push(arguments);
});
a.queue = [];
var s = 'script';
r = t.createElement(s);
r.async = !0;
r.src = n;
var u = t.getElementsByTagName(s)[0];
u.parentNode.insertBefore(r, u);
})(window, document, 'https://sc-static.net/scevent.min.js');
function initSnapchat(snapId, userEmail) {
snaptr('init', snapId, {
user_email: userEmail
});
}
function logEventSnapchat(pageView, obj) {
snaptr('track', pageView, obj);
}
</script>
<!-- End Snap Pixel Code -->
<!-- TikTok Pixel Code -->
<script>
!(function (w, d, t) {
w.TiktokAnalyticsObject = t;
var ttq = (w[t] = w[t] || []);
(ttq.methods = [
'page',
'track',
'identify',
'instances',
'debug',
'on',
'off',
'once',
'ready',
'alias',
'group',
'enableCookie',
'disableCookie'
]),
(ttq.setAndDefer = function (t, e) {
t[e] = function () {
t.push([e].concat(Array.prototype.slice.call(arguments, 0)));
};
});
for (var i = 0; i < ttq.methods.length; i++) ttq.setAndDefer(ttq, ttq.methods[i]);
(ttq.instance = function (t) {
for (var e = ttq._i[t] || [], n = 0; n < ttq.methods.length; n++)
ttq.setAndDefer(e, ttq.methods[n]);
return e;
}),
(ttq.load = function (e, n) {
var i = 'https://analytics.tiktok.com/i18n/pixel/events.js';
(ttq._i = ttq._i || {}),
(ttq._i[e] = []),
(ttq._i[e]._u = i),
(ttq._t = ttq._t || {}),
(ttq._t[e] = +new Date()),
(ttq._o = ttq._o || {}),
(ttq._o[e] = n || {});
var o = document.createElement('script');
(o.type = 'text/javascript'), (o.async = !0), (o.src = i + '?sdkid=' + e + '&lib=' + t);
var a = document.getElementsByTagName('script')[0];
a.parentNode.insertBefore(o, a);
});
})(window, document, 'ttq');
function initTiktokPixel(pixelId) {
ttq.load(pixelId);
}
function trackEvent(eventName, obj) {
ttq.track(eventName, obj);
}
</script>
<!-- End TikTok Pixel Code -->
<script>
function getURLParameter(name) {
console.log('location.search = ', location.search);
return (
decodeURIComponent(
(new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [
,
''
])[1].replace(new RegExp('\\+', 'g'), '%2B')
) || null
);
}
function locationHasChanged() {
if (location.href.indexOf('/booking/confirmation') != -1) {
var amount = getURLParameter('amount');
var transactionDocumentId = getURLParameter('transactionId');
var objGA = {
send_to: 'AW-604302093/RfE2CITy_P8BEI3Wk6AC',
value: amount,
currency: 'SAR',
transaction_id: transactionDocumentId
};
console.log('objG: ', objGA);
gtag('event', 'conversion', objGA);
}
}
let currentUrl = location.href;
const checkPageTransition = () => {
// requestAnimationFrame(() => {
if (currentUrl !== location.href) {
locationHasChanged();
}
currentUrl = location.href;
// }, true);
};
document.body.addEventListener('click', checkPageTransition);
window.addEventListener('load', function () {
console.log('LOAD ...');
});
</script>
<!-- Deep Link Adjust -->
<script>
// Function callback Custom-URL-scheme (Android).
function handleOpenURL(url) { sessionStorage.setItem('deepLinkAdjust', url) }
</script>
<script src="runtime-es2015.c2d98ede7b5e860b1261.js" type="module"></script><script src="runtime-es5.c2d98ede7b5e860b1261.js" nomodule defer></script><script src="polyfills-es5.8d609fa504ef0e3ff287.js" nomodule defer></script><script src="polyfills-es2015.7083b1229f85eaf01d71.js" type="module"></script><script src="scripts.fc3dae47aa26344b0dc0.js" defer></script><script src="main-es2015.81549ae55de7e98047a3.js" type="module"></script><script src="main-es5.81549ae55de7e98047a3.js" nomodule defer></script></body>
</html>
I am thinking about a way to inject HTML (text content) before the page is served to the client side in a meta tag or inside the body. So what is the best way to achieve this?