Category: Week 8

Redirecting your SPA on Netlify

In our project this week we built a single-page application. We wrote a custom “missing” page to display when the user routes to a non-existent page and gets a 404 HTTP response. However, when we deployed on Netlify the user gets server the default Netlify missing page which isn’t customised.

In the Netlify docs, the method to redirect routes on your application is to add a file with the name _redirects which outlines the rules for your paths.

Having the below in your _redirects file will redirect any non-existing paths to your missing.html page with a status code of 404:
/* /missing.html 404

Having the below in your _redirects file will redirect any non-existing paths to your index.html page with a status code of 200:
/* /index.html 200

Configuring servor npm package

This week we used the servor npm package to serve our single-page applications with front-end routing so we could render all our endpoints from one index.html.

I was having trouble running our application server locally on the correct port. The syntax from the servor docs is that it needs to know the following: <root> <fallback> <port>, so I had to add the below to my package.json file.

"scripts": { 
  "dev": "servor . index.html 3000" 
},

Making elements clickable and still accessible

If you have an element like a “card” on your webpage, and you want the whole element to be clickable, you might be tempted to wrap the link around the element like this:

<a href="https://www.google.com/" aria-label="link to google">
  <div class="card">
    <h2>Google</h2>
    <p>A popular search engine.</p>
  </div>
</a>

However, this solution is not ideal for screen readers because the aria-label may prevent the screen reader from reading the contents of the element. Rather than wrapping anchor tags around elements, you can use CSS to make the whole element clickable:

<div class="card">
  <h2>
    <a href="https://www.google.com/" aria-label="link to google">Google</a>
  </h2>
  <p>A popular search engine.</p>
</div>
.card a::before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

Where to put your <script> tags

Our practice so far in the course has been to put our <script> tags before the closing </body> tag in our HTML files. This is because when the browser encounters the <script> tag it blocks the parsing of the HTML and will not continue rendering the page until the JavaScript code has been downloaded and run. But the downside of including our JavaScript at the end of the HTML file is that the browser won’t start downloading the scripts at all until all of the page is parsed, which will affect the user experience if the files are very large.

In this week’s research spike we learned about the Critical Rendering Path, and how we can use the async or defer keywords in modern browsers to load our scripts in the <head> of our HTML files. These allow your scripts to be downloaded as soon as possible without blocking the HTML parsing.

Scripts with the async attribute are executed asynchronously in a casual order:
<script defer src="script.js"></script>

Scripts with the defer attribute are only executed after the entire document has been loaded:
http://script.js

Exporting modules in JS

So far in the course we have been doing server-side rendering for our projects with Node, but this week we are making single-page applications with client-side rendering.

Loading lots of <script> tags on our singular HTML file can slow the application down because each time a new script is encountered an HTTP request is made, and this blocks the rendering of the page.

Instead we can load our scripts as ES Modules, and the client will follow the import paths and execute each module once. We can do this by adding type="module" to the script tags on our HTML file.

<script type="module" src="app.js"></script>