There are many[1][2][3][4][5] people on internet that think a JWT shouldn't be stored inside localStorage.
In SPAs, unfortunately, it may not be possible to use HttpOnly cookies.
Here I use an iframe
and window.postMessage() cross-origin communication to securely store the token and handle user login.
Here you can find the code running inside the iframe.
This approach seems to expose less data in a possible XSS attack: code that runs outside the iframe shouldn't have access to user credentials, shouldn't be able to use key loggers or stole the token. Anyway, due to the hacky implementation, it might not be a good idea to use in production.
Live demo: https://hitbit-secure-localstorage.netlify.com
Please note that this is experimental work.