Don't like this style? Click here to change it! blue.css

LOGIN:
Welcome .... Click here to logout

Single Page Apps (Client-Side Routing)

Task: let users navigate to an infinite number of URLs in your app.

There are MANY ways to do this, but my flag for the day is one of them:

Minceraft

Let's group the various ways of doing this into several groups:

Single Page, no deep links

I'll start here because it's the simplest and most "conceptual".

Instead of a separate file per page we use a function to draw our new page.

All animation engines will wipe the screen and redraw it at least 20 times per second. We can use the same notion, clear the body or hide a div, now draw an appropriate page.

A simple Single Page App, no deep linking

Hosted at ./spa

An ASIDE: you'll want templating

Simple Templating / storing HTML for re-use

Here are some tricks for having unrendered HTML that you can keep up your sleeve for later.

Trick 1: multiple pages, all but one hidden.

See the Pen dGKyjZ by Andy Novocin (@AndyNovo) on CodePen.

Simple Pages: Add a fourth page template. Add a button on your page that when clicked alerts "hi".

Trick 2: multiple pages, all hidden, one display area.

See the Pen xZzxyq by Andy Novocin (@AndyNovo) on CodePen.

Simple Pages: Add a fourth to this example. What are the differences with the first trick. Any pros and cons that you can see?

Trick 3: script tags with bad types don't render.

See the Pen MKXWLa by Andy Novocin (@AndyNovo) on CodePen.

Simple Pages: Add a fourth. What are the differences? What are the pros and cons?

Trick 4: inline-template literals.

See the Pen version3 by Andy Novocin (@AndyNovo) on CodePen.

Simple Pages: Add a fourth to this example. What are the differences with the first trick. Any pros and cons that you can see?

For what it's worth, the 3rd trick is the one I see most often in simple page examples. Another trick is to keep separate HTML template files and use a library to help you load them.

Using URL params for deep linking

So this is the same as above but you can pack your data into URL parameters.

You see this a ton in marketing analytics links, there are many ways to call google.com with various params that don't change your results at all (but do tell them a lot about you).

I won't spend a ton of time on this, but here's how you can read URL params:

(Be careful with XSS)

Same app, using URL params

And the source code:

Using the hashchange event for Single Page Stuff

So the cool thing here is that the DOM has two events you can listen for that help us use an old thing in a new way:

https://css.prof.ninja/class15/route.html

Or link direct to #p3

All requests go to one spot

So far our URLs have been a tad ugly. ?blah=page2 or #page2 or no deep linking at all

But there's something beautiful about websec.prof.ninja/some/totally/unexpected/url

To pull that off we need a little help from the server. Here are three ways to get all requests to a certain URL to be handled by the same file:

Firebase Hosting and SPA-mode

This is important enough that I made a separate page for it:

Setup Firebase Hosting

When you do firebase init for hosting you'll select single Page App mode which sends all 404 errors to index.html

Node Static

Here's a demo for the second option (using NODE to augment your routing). The second is the one I use most often (a sample .htaccess follows). The third one is what I used for Minceraft

Head to Glitch.com and make a new "hello-node" app. Change the one line in server.js which said fastify.get("/", function(request, response) { and add the wildcard character: fastify.get("/*", function(request, response) { AND add the line wildcard: false to the "fastify-public" configuration. (If you're feeling lazy I've got an entire server.js below.) Visit your URL, then your URL/farts, then your URL/hello/world.

For posterity here's an .htaccess for sending all URLs to the same spot (a PHP file in this case):

The Frameworks

So all of these methods we've learned so far are under the hood of how the web app frameworks do it.

Thus, this section is almost to show you concepts of how you might consider engineering wrappers for your routing one day.

The REACT version

An ANGULAR routing example

Server-Side Routing

The earlier glitch example is essentially the hello world you need, but we'll do a whole bit on building REST APIs soon. So we can handle this case later. (In essence have the server handle /:param1/:param2 with some templating.)

Baby API

This is the same tech of a typical REST API, so here's a dumb example:

https://glitch.com/edit/#!/resolute-shimmer-forgery

Flag

Find my favorite mountain: ./flag

Second Flag

https://apricot-pinto-nectarine.glitch.me/