Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
preact-router
Advanced tools
Connect your Preact components up to that address bar.
preact-router
provides a <Router />
component that conditionally renders its children when the URL matches their path
. It also automatically wires up <a />
elements to the router.
💁 Note: This is not a preact-compatible version of React Router.
preact-router
is a simple URL wiring and does no orchestration for you.If you're looking for more complex solutions like nested routes and view composition, react-router works great with preact as long as you alias in preact-compat. React Router 4 even works directly with Preact, no compatibility layer needed!
import Router from 'preact-router';
import { h, render } from 'preact';
/** @jsx h */
const Main = () => (
<Router>
<Home path="/" />
<About path="/about" />
// Advanced is an optional query
<Search path="/search/:query/:advanced?" />
</Router>
);
render(<Main />, document.body);
If there is an error rendering the destination route, a 404 will be displayed.
:information_desk_person: Pages are just regular components that get mounted when you navigate to a certain URL.
Any URL parameters get passed to the component as props
.
Defining what component(s) to load for a given URL is easy and declarative.
You can even mix-and-match URL parameters and normal props
.
You can also make params optional by adding a ?
to it.
<Router>
<A path="/" />
<B path="/b" id="42" />
<C path="/c/:id" />
<C path="/d/:optional?/:params?" />
<D default />
</Router>
Lazy loading (code splitting) with preact-router
can be implemented easily using the AsyncRoute module:
import AsyncRoute from 'preact-async-route';
<Router>
<Home path="/" />
<AsyncRoute
path="/friends"
getComponent={ () => import('./friends').then(module => module.default) }
/>
<AsyncRoute
path="/friends/:id"
getComponent={ () => import('./friend').then(module => module.default) }
loading={ () => <div>loading...</div> }
/>
</Router>
preact-router
includes an add-on module called match
that lets you wire your components up to Router changes.
Here's a demo of <Match>
, which invokes the function you pass it (as its only child) in response to any routing:
import Router from 'preact-router';
import Match from 'preact-router/match';
render(
<div>
<Match path="/">
{ ({ matches, path, url }) => (
<pre>{url}</pre>
) }
</Match>
<Router>
<div default>demo fallback route</div>
</Router>
</div>
)
// another example: render only if at a given URL:
render(
<div>
<Match path="/">
{ ({ matches }) => matches && (
<h1>You are Home!</h1>
) }
</Match>
<Router />
</div>
)
<Link>
is just a normal link, but it automatically adds and removes an "active" classname to itself based on whether it matches the current URL.
import { Router, Link } from 'preact-router';
render(
<div>
<nav>
<Link activeClassName="active" href="/">Home</Link>
<Link activeClassName="active" href="/foo">Foo</Link>
<Link activeClassName="active" href="/bar">Bar</Link>
</nav>
<Router>
<div default>
this is a demo route that always matches
</div>
</Router>
</div>
)
Sometimes it's necessary to bypass preact-router's link handling and let the browser perform routing on its own.
This can be accomplished by adding a native
boolean attribute to any link:
<a href="/foo" native>Foo</a>
The Router
notifies you when a change event occurs for a route with the onChange
callback:
import { render, Component } from 'preact';
import { Router, route } from 'preact-router';
class App extends Component {
// some method that returns a promise
isAuthenticated() { }
handleRoute = async e => {
switch (e.url) {
case '/profile':
const isAuthed = await this.isAuthenticated();
if (!isAuthed) route('/', true);
break;
}
};
render() {
return (
<Router onChange={this.handleRoute}>
<Home path="/" />
<Profile path="/profile" />
</Router>
);
}
}
Can easily be implemented with a custom Redirect
component;
import { Component } from 'preact';
import { route } from 'preact-router';
export default class Redirect extends Component {
componentWillMount() {
route(this.props.to, true);
}
render() {
return null;
}
}
Now to create a redirect within your application, you can add this Redirect
component to your router;
<Router>
<Bar path="/bar" />
<Redirect path="/foo" to="/bar" />
</Router>
It's possible to use alternative history bindings, like /#!/hash-history
:
import { h } from 'preact';
import Router from 'preact-router';
import { createHashHistory } from 'history';
const Main = () => (
<Router history={createHashHistory()}>
<Home path="/" />
<About path="/about" />
<Search path="/search/:query" />
</Router>
);
render(<Main />, document.body);
Its possible to programmatically trigger a route to a page (like window.location = '/page-2'
)
import { route } from 'preact-router';
route('/page-2') // appends a history entry
route('/page-3', true) // replaces the current history entry
FAQs
Connect your components up to that address bar.
The npm package preact-router receives a total of 14,845 weekly downloads. As such, preact-router popularity was classified as popular.
We found that preact-router demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 9 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.