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?
- Request a new HTML document. The page goes blank.
- As the HTML loads, request any
<script>
or<link>
resources. - A
<script>
may mutate the document, so these tags block rendering. - 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
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!
Change the URL, but do not trigger a page load.
This will add a new entry to the browser history.
Check out the elm/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.
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.
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!
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
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://elm-lang.org"
Check out the elm/url
package for help building URLs. The
Url.absolute
and Url.relative
functions can be particularly
handy!
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.
Reload the current page without using the browser cache. This always
results in a page load! It is more common to want reload
.