Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save Olaw2jr/55df306ca4b537fc19b2b9a4e2b3ca3f to your computer and use it in GitHub Desktop.

Select an option

Save Olaw2jr/55df306ca4b537fc19b2b9a4e2b3ca3f to your computer and use it in GitHub Desktop.

Everything I Know About UI Routing

Ingredients

  1. Location
    1. pathname
    2. state
    3. search/query
    4. hash
  2. Path
    1. Dynamic Segment
    2. Wild Card
    3. Regex
  3. Matching
    1. URI
    2. Parameters
    3. State
    4. Query
  4. History
    1. Listener
    2. State
    3. History Stack (push/replace/index)
  5. Routes
    1. Path
    2. Data
    3. Validation
  6. Links
    1. href
    2. state
    3. active status
  7. File System API

tl;dr On Client Side Routing

When a user visits a webpage, the location is the the first (and probably the only) data the app has to generate a UI. The location is matched against a set of routes, a route is selected, (maybe) data is loaded, and finally the UI is rendered.

After the initial render on the client, a history listener is set up. When the history's location changes--either through the user clicking links or the programmer redirecting with code--the new location is matched against the routes, (maybe) data is fetched, and the app is updated to the new page.

Some implementations will save the data loading of a route for after the new page is rendered (and display some spinners). There are a handful of tradeoffs regarding data loading on page transitions, so we'll save that conversation for later.

Server Side Approaches

Before we can talk much about anything else, we have to

There are three approaches to UI routing on the server:

  1. "Single Page App"
  2. Static File Generation
  3. Serverside Pre-Rendering

"Single Page App"

A traditional website handles URLs on the server. This can be as simple as an html file for each page of your site: /about.html, /contact.html etc.

In order for a client side router to work, every URL the server receives needs to run the same application. A bare-bones express server would look like this:

const express = require('express')
const app = express()

// serve all static files that exist as the file (CSS, JS, etc.)
app.use(express.static('public'))

// serve every other request to your root app html file
app.get('*', (res) => {
  res.sendFile(path.join(__dirname, 'app.html'))
})

app.listen(5000)

Now if the user visits /invoices/123 they will get the app.html file, and then the client side router will match the URL, fetch the invoice, and render the page.

Setup for a server rendered app

If you want to render the initial screen on the server (some folks call it pre-rendering) there's a bit more to it.

Code Splitting and Bundle Size Concerns

Server Rendering

Data Loading

Clientside Page Transitions

Accessibility: Scroll Restoration

Accessibility: Focus Management

Animation

Dynamic Routes (Screen Size, Authentication, etc.)

Navigation Based Matching (instagram)

Relative Routes, Links

Navigation Blocking

Queries

History Stack

Mobile

File System API

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment