
Security News
High Salaries No Longer Enough to Attract Top Cybersecurity Talent
A survey of 500 cybersecurity pros reveals high pay isn't enough—lack of growth and flexibility is driving attrition and risking organizational security.
Simple named url patterns in JavaScript.
Implementing a static route config and named routes on top of (react-router) at this point is like a 20 line ordeal. – Ryan Florence
Named routes are essential to keep route config DRY and prevent silly errors
due to typos. This feature was removed from react-router
in 1.0 and I missed
it since then as many
others.
There're other libs dealing with named routes, some of them provide custom
Link
, Route
routes, some of them have more features to integrate with
express
. Here's incomplete list of libs I considered before writing these
20 lines of code (and 200+ lines of other files to publish this package):
NOTE: v2 introduces breaking changes. Please check out the migration guide before upgrading.
$ npm install named-urls
or
$ yarn add named-urls
Create file with all routes in your application (e.g. routes.js
). Use
named-urls/include
to create namespaced group of routes with common prefix:
// routes.js
import { include } from 'named-urls'
export default {
// simple route
profile: '/profile',
// route with params
article: '/article/:articleId',
// route with optional params
messages: '/messages/:messageId?',
// Routes with common path prefix
auth: include('/auth', {
// Absolute url (ignore /auth prefix)
login: '/login/',
// Relative urls (prefixed with /auth)
passwordReset: 'password/reset/',
passwordVerify: 'password/verify/',
}),
// Routes with params
messages: include('/messages', {
all: '',
unread: 'unread/',
// nesting of includes is allowed
detail: include(':messageId/', {
show: '',
edit: 'edit/',
comments: 'comments/',
})
})
}
Use routes in Route
component from react-router-dom
:
// App.js
import React from 'react'
import { Switch, Route } from 'react-router-dom'
import routes from './routes'
import * as scenes from './scenes' // just a convention, could be "pages"
function App() {
return (
<Switch>
<Route path={routes.profile} component={scenes.Profile} />
<Route path={routes.auth.login} component={scenes.auth.Login} />
// ...
<Route path={routes.messages.unread} component={scenes.messages.Unread} />
<Route path={routes.messages.detail.show} component={scenes.messages.Detail} />
</Switch>
)
}
Routes with parameters can be formatted using reverse
function:
// Navigation.js
import React from 'react'
import { Link } from 'react-router'
import { reverse } from 'named-urls'
function Navigation({ messages }) {
return (
<ul>
<li><Link to={`${routes.profile}`}>Profile</Link></li>
// ...
// Use reverse to replace params in route pattern with values
{messages.map(message =>
<li key={message.id}>
<Link to={reverse(`${routes.messages.detail.show}`, { messageId: message.id })}>
Profile
</Link>
</li>
)}
</ul>
)
}
Patterns ending with slash are always reversed to URL with ending slash and vice versa: Paterns without ending slash are always reserved to URL without endlish slash:
// pattern with ending slash
reverse('pattern/:optional?', { optional: 42 }) // pattern/42
reverse('pattern/:optional?') // pattern
// pattern without ending slash
reverse('pattern/:optional?/', { optional: 42 }) // pattern/42/
reverse('pattern/:optional?/') // pattern/
For better compatibility with React Router, v2 uses path-to-regexp to resolve URLs. This means some of your routes may break when you upgrade.
reverse
-reverse('pattern/page:param?', {})
+reverse('pattern/(page:param)?', {})
reverseForce
-reverseForce('pattern/page:param?', {})
+reverseForce('pattern/(page:param)?', {})
To get a full overview of all accepted patterns, consult the path-to-regexp documentation.
If you define a route as an include, calling it directly will return you a function. To by-pass that, you have a solution to create an empty route inside, let's call it self
:
// routes.js
import { include } from 'named-urls'
export default {
messages: include('/messages', {
self: '',
detail: include(':messageId/', {
show: '',
edit: 'edit/',
comments: 'comments/',
})
})
}
so you'll be able to do:
<Route path={routes.messages.self} component={Messages} />
A way to not define a useless route is to use the string way of a route like that:
// routes.js
import { include } from 'named-urls'
export default {
messages: include('/messages', {
detail: include(':messageId/', {
edit: 'edit/',
comments: 'comments/',
})
})
}
<Route path={`${routes.messages}`} component={Messages} />
// OR
<Route path={String(routes.messages)} component={Messages} />
FAQs
Simple named url patterns in Javascript
The npm package named-urls receives a total of 4,745 weekly downloads. As such, named-urls popularity was classified as popular.
We found that named-urls demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 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
A survey of 500 cybersecurity pros reveals high pay isn't enough—lack of growth and flexibility is driving attrition and risking organizational security.
Product
Socket, the leader in open source security, is now available on Google Cloud Marketplace for simplified procurement and enhanced protection against supply chain attacks.
Security News
Corepack will be phased out from future Node.js releases following a TSC vote.