Highway is a lightweight (2ko gzipped), robust, modern and flexible library that will let you create AJAX navigations with beautiful transitions on your websites. It's been a while we were trying to build this kind of library to fits our needs at Dogstudio and that hopefully will fit yours now we're releasing it!
You can install Highway the way you want between these two methods:
With YARN:
yarn add @dogstudio/highway
With NPM:
npm install --save @dogstudio/highway
Now you have installed Highway it's time to dive into how you can use it... And you know what? It's pretty simple.
First let's import Highway:
import Highway from '@dogstudio/highway';Now Highway is available you need to create an instance of Highway.Core and give it your renderers and transitions.
const H = new Highway.Core({
renderers: {
[...]
},
transitions: {
[...]
}
});Finally, in order to work properly Highway needs a basic HTML structure. All you have to do is to put somewhere in your pages the router-wrapper that will contain and only contain the router-view. You need to understand that Highway will only change the router-view presents in the router-wrapper. Everything outside of the router-wrapper will stay the same all along the user's navigation.
<!-- [...] -->
<body>
<!-- [...] -->
<main router-wrapper>
<article router-view>
<!-- [...] -->
</article>
</main>
<!-- [...] -->
</body>
<!-- [...] -->And voilà!
You are now ready to create some beautiful and creative transitions between your pages.
Everytime you create a page that needs its own Javascript to work you need to relate it to a custom renderer. This way Highway will be able to call the page's Javascript during the transition. Luckily we have done almost all the work for you, great isn't it? However you have a part to play in this and here is how you can setup properly your custom renderers.
Note: If your page doesn't have any Javascript related to it you don't need to create a custom renderer for it.
About your HTML this is actually pretty simple... Remember the router-view you added to your DOM? You are going to name it and the name you are going to give to your router-view will be used later to identify it and relate it to the correct custom renderer in Javascript.
index.html
<!-- [...] -->
<body>
<!-- [...] -->
<main router-wrapper>
<article router-view="home">
<!-- [...] -->
</article>
</main>
<!-- [...] -->
</body>
<!-- [...] -->On the Javascript-side it's again pretty simple... What you need to do is to create a custom renderer for your page that will extend Highway.Renderer and enable all the required methods in order to make your custom renderer work.
home.js
// Import Highway
import Highway from '@dogstudio/highway';
class Home extends Highway.Renderer {
[...]
}
// Don`t forget to export your renderer
export default Home;Besides the required methods from Highway present in the Highway.Renderer you have access to optional ones that are called all along the process of the navigation. Here is the list of these optional methods:
onEnter: Called when the transitioninstarts & therouter-viewis added torouter-wrapper.onLeave: Called when the transitionoutstarts.onEnterCompleted: Called when the transitioninis over.onLeaveCompleted: Called when the transitionoutis over & therouter-viewis removed fromrouter-wrapper.
Highway.Renderer also gives you access to useful variables you will be able to use in your own code:
this.page: The full DOM of the page related to the renderer.this.view: The[router-view]of the page related to the renderer.
home.js
// Import Highway
import Highway from '@dogstudio/highway';
class Home extends Highway.Renderer {
onEnter() { }
onLeave() { }
onEnterCompleted() { }
onLeaveCompleted() { }
}
// Don`t forget to export your renderer
export default Home;Now your custom renderer is created you need to add it to the renderers list of Highway.Core...
Remember the name you gave to your router-view, it's now time to relate it to your custom renderer.
// Import Renderers
import Home from 'path/to/home.js';
// Relate you renderer to your [router-view] name
const H = new Highway.Core({
renderers: {
home: Home
},
transitions: {
[...]
}
});OK so now you have your custom renderers but you are sad because there are no transitions between your pages...
Don't be afraid, let's now see how to create our first transition!
Transitions in Highway are really simple, you need to extend Highway.Transition and provide two required methods:
in: Theinmethod should contain the transition to show a[router-view].out: Theoutmethod should contain the transition to hide a[router-view].
Each one get two parameters you can name howewer you want but here are good defaults:
view: The[router-view]you will show/hide.done: The callback method you have to call once theinandouttransitions are over.
transition.js
// Import Highway
import Highway from '@dogstudio/highway';
class Transition extends Highway.Transition {
in(view, done) {
// [...]
}
out(view, done) {
// [...]
}
}
// Don't forget to export your transition
export default Transition;Now your transition is created you need to add it to the transitions list of Highway.Core...
Remember the name you gave to you router-view, it's now time to relate it to your transition.
// Import Renderers
import Home from 'path/to/home.js';
// Import Transitions
import Transition from 'path/to/transition.js';
// Relate you transition to your [router-view] name
const H = new Highway.Core({
renderers: {
home: Home
},
transitions: {
home: Transition
}
});Finally you might want to use the same transition for all the pages across your website. This is possible by adding a default key to your transitions list. When you do so, for each page, Highway will look for a transition in the list related to your router-view name and fallback to the default one if none is found.
// [...]
const H = new Highway.Core({
renderers: {
home: Home
},
transitions: {
default: Transition
}
});Check out the examples for more details about transitions in Highway.
Last but not least, Highway extends tiny-emitter to send events along the navigation process you can listen to in order to extend its capabilities. There are three events available for you:
NAVIGATE_OUT: Trigger when a click is clicked and theouttransition starts.NAVIGATE_IN: Trigger when theintransition starts.NAVIGATE_END: Trigger when a navigation ends.NAVIGATE_ERROR: Trigger when an error occurs in navigation process.
All events give you access to some parameters named:
from: The renderer of the page you come from.to: The renderer of the page you go to.state: The state of Highway that contains all the informations about the URL of the page you go to.error: The error that occured during the navigation related to the HTTP request.
// [...]
H.on('NAVIGATE_IN', (to, state) => {
// [...]
});
H.on('NAVIGATE_OUT', (from, state) => {
// [...]
});
H.on('NAVIGATE_END', (from, to, state) => {
// [...]
});
H.on('NAVIGATE_ERROR', (error) => {
// [...]
});
// [...]Check out the Basic Menu Active example for more details about events handling in Highway.
- Basic Setup
- Basic Transition
- Basic CSS Transition
- Basic Menu Active
- Basic Anchor
- Basic Google Analytics Events
- Basic Polyfill
Take part of our journey and tweet us your most beautiful projects using Highway to @Dogstudio or @Anthodpnt. The most interesting ones will be featured here. Thanks!
Note that Highway uses modern features because we wanted it to be modern. This means some browser might not support some of these modern features and you'll have to add a polyfill to your projects like babel-polyfill or transpile your code to ES5 using tools like Webpack. This is a non-exhaustive list of modern features used in Highway:
- Classes
- Object/Array Destructuring
- Maps
- Promises
- Async...Await Functions
- Fetch API
- ...
Check out the Basic Polyfill example to know how to polyfill Highway. This example is compatible with:
- Google Chrome
- Safari
- Firefox
- Edge
- IE11
- More Unit Tests
- More Examples
- More Demos
- Add the
Basic Anchorexample - Add the
Basic Polyfillexample - Add unit tests
- Remove modes that weren't convincing
- Improve code and weight with ES2016+ features
- Improve events
- Improve transitions
- Improve documentation
- Fix events
- Fix helpers
- Add
NAVIGATE_CALL,NAVIGATE_IN,NAVIGATE_OUTevents - Add more variables available in
Highway.Renderer - Improve renderers
- Improve documentation
- Add modes
- Improve documentation
- Add
Highway.Transition
- First release
See the LICENSE file for license rights and limitations (MIT).
