Routing - ProjectEvergreen/create-evergreen-app GitHub Wiki
If you're interested in helping us with writing documentation for this, please feel free to comment in this issue and say hi! 👋
Routing with web components can be achieved using a redux based solution with the lit-redux-router package.
npx create-evergreen-app my-app
cd my-app
npm start
npm install lit-element lit-html lit-redux-router redux pwa-helpers
Create a new redux store ./app/store.js
import { createStore, compose as origCompose, combineReducers } from 'redux';
import { lazyReducerEnhancer } from 'pwa-helpers/lazy-reducer-enhancer.js';
// eslint-disable-next-line no-underscore-dangle
const compose = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || origCompose;
// eslint-disable-next-line
const store = createStore(
(state, action) => state, // eslint-disable-line
compose(lazyReducerEnhancer(combineReducers))
);
export default store;
Create 3 new page components in ./pages/home/
e.g. docs.js
, home.js
, about.js
Place the following content in each, modify with the page name:
home.js
import { html, LitElement } from '@polymer/lit-element';
class HomePageComponent extends LitElement {
render() {
return html`
<div class="container">
<h1>Home</h1>
</div>
`;
}
}
customElements.define('home-page', HomePageComponent);
about.js
import { html, LitElement } from '@polymer/lit-element';
class AboutPageComponent extends LitElement {
render() {
return html`
<div class="container">
<h1>About</h1>
</div>
`;
}
}
customElements.define('about-page', AboutPageComponent);
docs.js
import { html, LitElement } from '@polymer/lit-element';
class DocsPageComponent extends LitElement {
render() {
return html`
<div class="container">
<h1>Documentation</h1>
</div>
`;
}
}
customElements.define('docs-page', DocsPageComponent);
In your ./app/app.js
file:
First import the dependencies
import { html, LitElement } from '@polymer/lit-element';
import { connectRouter } from 'lit-redux-router';
import store from './store.js';
import css from './app.css';
import '../components/header/header.js';
import '../pages/home/docs.js';
import '../pages/home/home.js';
import '../pages/home/about.js';
Next underneath the dependencies you need to connect the router to the store.
connectRouter(store);
Each <lit-route></lit-route>
element requires a path
attribute with a string for each page and component
attribute with the string name of the component page element.
Within your component's render function you can add each route, here's a complete example:
import { html, LitElement } from '@polymer/lit-element';
import { connectRouter } from 'lit-redux-router';
import store from './store.js';
import css from './app.css';
import '../components/header/header.js';
import '../pages/home/docs.js';
import '../pages/home/home.js';
import '../pages/home/about.js';
connectRouter(store);
class AppComponent extends LitElement {
render() {
return html`
<style>
${css}
</style>
<div>
<eve-header></eve-header>
<lit-route path="/" component="home-page"></lit-route>
<lit-route path="/about" component="about-page"></lit-route>
<lit-route path="/docs" component="docs-page"></lit-route>
<lit-route><h1>404 Not found</h1></lit-route>
</div>
`;
}
}
customElements.define('eve-app', AppComponent);
Note: When no path attribute is specified, the router will render the child elements whenever there is a 404
Using the above example, we can modify our path attribute on any route to include path variables
for example in ./app/app.js
modify:
<lit-route path="/docs/:somepage" component="docs-page'}"></lit-route>
You can then modify the ./pages/home/docs.js
component to use that variable:
import { html, LitElement } from 'lit-element';
class DocsPageComponent extends LitElement {
static get properties() {
return {
somepage: String
};
}
render() {
return html`
<div class="container">
<h1>${this.somepage}</h1>
</div>
`;
}
}
customElements.define('docs-page', DocsPageComponent);
Now visit your http://localhost:1981/docs/my-test-page to see the path variable display
To navigate route without reloading the page, modify the ./pages/home/home.js
component to use store.dispatch(navigate(path))
:
import { html, LitElement } from 'lit-element';
import { navigate } from 'lit-redux-router';
import store from '../../app/store.js';
class HomePageComponent extends LitElement {
pushPath(path) {
store.dispatch(navigate(path));
}
render() {
return html`
<div>
<p>To get started, <button @click="${() => this.pushPath('/about')}">View About</button>
</div>
`;
}
}
customElements.define('home-page', HomePageComponent);