<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jeff Galbraith</title>
    <description>The latest articles on DEV Community by Jeff Galbraith (@hawkeye64).</description>
    <link>https://dev.to/hawkeye64</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F99832%2F573deafa-f02a-4b23-b74e-2e63ea5feca3.png</url>
      <title>DEV Community: Jeff Galbraith</title>
      <link>https://dev.to/hawkeye64</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hawkeye64"/>
    <language>en</language>
    <item>
      <title>Publish your Quasar SPA on Github.io with History Mode</title>
      <dc:creator>Jeff Galbraith</dc:creator>
      <pubDate>Sun, 20 Oct 2019 12:59:12 +0000</pubDate>
      <link>https://dev.to/quasar/publish-your-quasar-spa-on-github-io-with-history-mode-20h2</link>
      <guid>https://dev.to/quasar/publish-your-quasar-spa-on-github-io-with-history-mode-20h2</guid>
      <description>&lt;h2&gt;
  
  
  Frustrated with Github.io, because you can't run your Quasar SPA in history mode? Well, now you can!
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Introduction
&lt;/h4&gt;

&lt;p&gt;This article is intended to help you get your SPA published on Github.io with history mode turned on. This isn't a straight up process, so I figured I'd write some instructions on how to do it, to help out others who might be running into problems with this process. &lt;/p&gt;

&lt;h4&gt;
  
  
  Vue-Router
&lt;/h4&gt;

&lt;p&gt;Vue-Router has two modes; 1) &lt;strong&gt;hash&lt;/strong&gt; and 2) &lt;strong&gt;history&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;hash&lt;/strong&gt; mode, there is only a single web page and routing takes over to display your pages correctly. Any backend server will be set up to serve only the index file.&lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;history&lt;/strong&gt; mode, the concept is similar. However, the server is expecting static pages and for it to be handling the routing. If you have control over your own server, you would write some rewrite rules so the index file will be loaded, and just the index file, for every page, so the vue-router can take over from there.&lt;/p&gt;

&lt;p&gt;So, you might also be asking yourself...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If &lt;strong&gt;hash&lt;/strong&gt; mode works fine on github.io, why would anyone want to use &lt;strong&gt;history&lt;/strong&gt; mode?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For myself, I wanted to be able to use anchor links. So, given a url with a hash symbol in it, the proper page will load up and content will automatically scroll to the anchor link.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Conumdrum with Github.io
&lt;/h4&gt;

&lt;p&gt;At the time I was investigating this, github.io didn't allow you to write any sort of server rewrite rules. The information I found was sparse. Maybe it can be done, as I did this a while ago and things change. I can only tell you what worked for me then and still works for me now.&lt;/p&gt;

&lt;h4&gt;
  
  
  publicPath
&lt;/h4&gt;

&lt;p&gt;Inside your &lt;code&gt;quasar.conf.js&lt;/code&gt; you can set up the &lt;code&gt;publicPath&lt;/code&gt;. What this does is put the public path data from the &lt;code&gt;publicPath&lt;/code&gt; variable in front of all your resource calls.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;vueRouterMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;history&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;publicPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-extension-qmarkdown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the &lt;code&gt;publicPath&lt;/code&gt;? This is for my component, QMarkdown, which lives at &lt;a href="https://github.com/quasarframework/app-extension-qmarkdown"&gt;https://github.com/quasarframework/app-extension-qmarkdown&lt;/a&gt;. And, the github.io url would be this: &lt;a href="https://quasarframework.github.io/app-extension-qmarkdown"&gt;https://quasarframework.github.io/app-extension-qmarkdown&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Using this &lt;code&gt;publicPath&lt;/code&gt; allows me to develop locally and then, when I build the site, the &lt;code&gt;publicPath&lt;/code&gt; is injected so resources can properly be found by the browser.&lt;/p&gt;

&lt;h4&gt;
  
  
  The 404 on Github.io
&lt;/h4&gt;

&lt;p&gt;If you drop a &lt;strong&gt;404.html&lt;/strong&gt; into root of your SPA app, when a page is not found, it will be called. Since vue-router will be managing the routing, this &lt;strong&gt;404.html&lt;/strong&gt; page will be called for any presumably static page that doesn't exist (meaning, all your routes!).&lt;/p&gt;

&lt;p&gt;I came up with a way to leverage this &lt;strong&gt;404.html&lt;/strong&gt; file. It took a while (over a week) to figure this all out and finalize it.&lt;/p&gt;

&lt;p&gt;Basically, this is what your &lt;strong&gt;404.html&lt;/strong&gt; should look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;404 Redirect&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;redirect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv=&lt;/span&gt;&lt;span class="s"&gt;"refresh"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"0;URL='/app-extension-qmarkdown'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/meta&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
&lt;span class="ni"&gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;/span&gt;
&lt;span class="ni"&gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;/span&gt;
&lt;span class="ni"&gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;


&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the &lt;code&gt;meta&lt;/code&gt; tag with &lt;strong&gt;URL&lt;/strong&gt;. This needs to match your &lt;code&gt;publicPath&lt;/code&gt; route in order for it to work.&lt;/p&gt;

&lt;p&gt;You may also be wondering why there are all the spaces between the &lt;code&gt;body&lt;/code&gt; tags. There was some issue with Internet Explorer. If the file was too small, it just wouldn't read it.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Last Trick
&lt;/h4&gt;

&lt;p&gt;The &lt;strong&gt;404.html&lt;/strong&gt; is running a snippet of JavaScript to put the current route into &lt;code&gt;sessionStorage&lt;/code&gt;. This is key to getting this all to work. We have to use this &lt;code&gt;sessionStorage&lt;/code&gt; to get back on track with vue-router.&lt;/p&gt;

&lt;p&gt;In your &lt;code&gt;index.template.html&lt;/code&gt; file, you can add the following between the body tags:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
          &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;redirect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;redirect&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;redirect&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replaceState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;})();&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="c"&gt;&amp;lt;!--&lt;/span&gt; &lt;span class="nx"&gt;DO&lt;/span&gt; &lt;span class="nx"&gt;NOT&lt;/span&gt; &lt;span class="nx"&gt;touch&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;following&lt;/span&gt; &lt;span class="nx"&gt;DIV&lt;/span&gt; &lt;span class="o"&gt;--&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;q-app&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/body&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, &lt;code&gt;sessionStorage&lt;/code&gt; is read, deleted and then history is put back in place. Now, vue-router can take over without issues occurring in the browser.&lt;/p&gt;

&lt;h4&gt;
  
  
  Final Words
&lt;/h4&gt;

&lt;p&gt;The above happens so fast, you would never know what's happening behind the scenes.&lt;/p&gt;

&lt;p&gt;It is my hope that this helps others leverage github.io in history mode, just as it has helped me.&lt;/p&gt;

&lt;p&gt;Are you using Github.io for publishing your SPA? Let's us also know your experiences or give us feedback about this article. We'd love to hear from you. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interested in Quasar? Here are some more tips and information:&lt;/strong&gt;&lt;br&gt;
More info: &lt;a href="https://quasar.dev"&gt;https://quasar.dev&lt;/a&gt;&lt;br&gt;
GitHub: &lt;a href="https://github.com/quasarframework/quasar"&gt;https://github.com/quasarframework/quasar&lt;/a&gt;&lt;br&gt;
Getting Started: &lt;a href="https://quasar.dev/start"&gt;https://quasar.dev/start&lt;/a&gt;&lt;br&gt;
Chat Server: &lt;a href="https://chat.quasar.dev/"&gt;https://chat.quasar.dev/&lt;/a&gt;&lt;br&gt;
Forum: &lt;a href="https://forum.quasar.dev/"&gt;https://forum.quasar.dev/&lt;/a&gt;&lt;br&gt;
Twitter: &lt;a href="https://twitter.com/quasarframework"&gt;https://twitter.com/quasarframework&lt;/a&gt;&lt;br&gt;
Donate: &lt;a href="https://donate.quasar.dev"&gt;https://donate.quasar.dev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>github</category>
      <category>vue</category>
      <category>quasar</category>
    </item>
  </channel>
</rss>
