I am implementing session token in our existing shopify app, It is a multi page application so I am using turbolink (suggested by shopify docs).
See the below code that I’m using for generating Session Token.
<script src="https://unpkg.com/@shopify/app-bridge@2"></script>
<script src="https://unpkg.com/@shopify/app-bridge-utils"></script>
<script type="module">
var host = "<?= \Session::get('host') ?>";
const SESSION_TOKEN_REFRESH_INTERVAL = 2000;
function retrieveToken(app) {
window['app-bridge-utils'].getSessionToken(app).then(token => {
window.sessionToken = token;
});
}
document.addEventListener("turbolinks:request-start", function(event) {
retrieveToken(app);
var xhr = event.data.xhr;
xhr.setRequestHeader("Authorization", "Bearer " + window.sessionToken);
});
document.addEventListener("turbolinks:render", function() {
$("form, a[data-method=delete]").on("ajax:beforeSend", function(event) {
const xhr = event.detail[0];
xhr.setRequestHeader("Authorization", "Bearer " + window.sessionToken);
});
});
document.addEventListener("DOMContentLoaded", async () => {
var data = document.getElementById("shopify-app-init").dataset;
var AppBridge = window["app-bridge"];
var createApp = AppBridge.default;
window.app = createApp({
apiKey: '<?= env('App_Client_Id'); ?>',
host: host,
});
var actions = AppBridge.actions;
var TitleBar = actions.TitleBar;
TitleBar.create(app, {
title: data.page,
});
// Wait for a session token before trying to load an authenticated page
await retrieveToken(app);
// Keep retrieving a session token periodically
keepRetrievingToken(app);
// Redirect to the requested page when DOM loads
var isInitialRedirect = true;
redirectThroughTurbolinks(isInitialRedirect);
document.addEventListener("turbolinks:load", function(event) {
redirectThroughTurbolinks();
});
// Helper functions
function redirectThroughTurbolinks(isInitialRedirect = false) {
var data = document.getElementById("shopify-app-init").dataset;
var validLoadPath = data && data.loadPath;
var shouldRedirect = false;
switch (isInitialRedirect) {
case true:
shouldRedirect = validLoadPath;
break;
case false:
shouldRedirect = validLoadPath && data.loadPath !== "<?= url("/shopify/dashboard") ?>"; // Replace with the app's home_path
break;
}
if (shouldRedirect) Turbolinks.visit(data.loadPath);
}
function keepRetrievingToken(app) {
setInterval(() => {
retrieveToken(app);
}, SESSION_TOKEN_REFRESH_INTERVAL);
}
});
</script>
Problem: The “turbolinks:request-start” event is running before “DOMContentLoaded” event, due to this behaviour, token is not added on the first request’s header.
Does this is expected behaviour?