Browser.Navigation

This module helps you manage the browser’s URL yourself. This is the crucial trick when using Browser.application.

The most important function is pushUrl which changes the address bar without starting a page load.

What is a page load?

  1. Request a new HTML document. The page goes blank.
  2. As the HTML loads, request any <script> or <link> resources.
  3. A <script> may mutate the document, so these tags block rendering.
  4. When all of the assets are loaded, actually render the page.

That means the page will go blank for at least two round-trips to the servers! You may have 90% of the data you need and be blocked on a font that is taking a long time. Still blank!

How does pushUrl help?

The pushUrl function changes the URL, but lets you keep the current HTML. This means the page never goes blank. Instead of making two round-trips to the server, you load whatever assets you want from within Gren. Maybe you do not need any round-trips! Meanwhile, you retain full control over the UI, so you can show a loading bar, show information as it loads, etc. Whatever you want!

Navigate within Page

type Key

A navigation Key is needed to create navigation commands that change the URL. That includes pushUrl, replaceUrl, back, and forward.

You only get access to a Key when you create your program with Browser.application, guaranteeing that your program is equipped to detect these URL changes. If Key values were available in other kinds of programs, unsuspecting programmers would be sure to run into some annoying bugs and learn a bunch of techniques the hard way!

pushUrl : Key -> String -> Cmd msg

Change the URL, but do not trigger a page load.

This will add a new entry to the browser history.

Check out the gren-lang/url package for help building URLs. The Url.Builder.absolute and Url.Builder.relative functions can be particularly handy!

Note: If the user has gone back a few pages, there will be “future pages” that the user can go forward to. Adding a new URL in that scenario will clear out any future pages. It is like going back in time and making a different choice.

replaceUrl : Key -> String -> Cmd msg

Change the URL, but do not trigger a page load.

This will not add a new entry to the browser history.

This can be useful if you have search box and you want the ?search=hats in the URL to match without adding a history entry for every single key stroke. Imagine how annoying it would be to click back thirty times and still be on the same page!

Note: Browsers may rate-limit this function by throwing an exception. The discussion here suggests that the limit is 100 calls per 30 second interval in Safari in 2016. It also suggests techniques for people changing the URL based on scroll position.

back : Key -> Int -> Cmd msg

Go back some number of pages. So back 1 goes back one page, and back 2 goes back two pages.

Note: You only manage the browser history that you created. Think of this library as letting you have access to a small part of the overall history. So if you go back farther than the history you own, you will just go back to some other website!

forward : Key -> Int -> Cmd msg

Go forward some number of pages. So forward 1 goes forward one page, and forward 2 goes forward two pages. If there are no more pages in the future, this will do nothing.

Note: You only manage the browser history that you created. Think of this library as letting you have access to a small part of the overall history. So if you go forward farther than the history you own, the user will end up on whatever website they visited next!

Navigate to other Pages

load : String -> Cmd msg

Leave the current page and load the given URL. This always results in a page load, even if the provided URL is the same as the current one.

gotoGrenWebsite : Cmd msg
gotoGrenWebsite =
    load "https://gren-lang.org"

Check out the gren-lang/url package for help building URLs. The Url.absolute and Url.relative functions can be particularly handy!

reload : Cmd msg

Reload the current page. This always results in a page load! This may grab resources from the browser cache, so use reloadAndSkipCache if you want to be sure that you are not loading any cached resources.

reloadAndSkipCache : Cmd msg

Reload the current page without using the browser cache. This always results in a page load! It is more common to want reload.