### Install Universal Router via npm Source: https://github.com/kriasoft/universal-router/blob/main/docs/getting-started.md Instructions to install the Universal Router library using npm, saving it as a dependency in the project. ```sh npm install universal-router --save ``` -------------------------------- ### Basic Universal Router Usage with JavaScript Source: https://github.com/kriasoft/universal-router/blob/main/docs/getting-started.md Demonstrates how to define routes and resolve a path using Universal Router in plain JavaScript. It shows route structure with path and action properties, and how to render the result to the document body. ```js import UniversalRouter from 'universal-router' const routes = [ { path: '/one', action: () => '

Page One

' }, { path: '/two', action: () => '

Page Two

' }, { path: '/*all', action: () => '

Not Found

' }, ] const router = new UniversalRouter(routes) router.resolve({ pathname: '/one' }).then((result) => { document.body.innerHTML = result // renders:

Page One

}) ``` -------------------------------- ### Universal Router Integration with React Source: https://github.com/kriasoft/universal-router/blob/main/docs/getting-started.md Illustrates how to use Universal Router with React, defining routes that return React components and rendering them using ReactDOM.render. ```jsx import React from 'react' import ReactDOM from 'react-dom' import UniversalRouter from 'universal-router' const routes = [ { path: '/one', action: () =>

Page One

}, { path: '/two', action: () =>

Page Two

}, { path: '/*all', action: () =>

Not Found

}, ] const router = new UniversalRouter(routes) router.resolve({ pathname: '/one' }).then((component) => { ReactDOM.render(component, document.body) // renders:

Page One

}) ``` -------------------------------- ### Include Universal Router via CDN Source: https://github.com/kriasoft/universal-router/blob/main/docs/getting-started.md Provides script tags to include Universal Router and its related modules directly from a CDN, useful for client-side package management without npm. ```html ``` -------------------------------- ### Install Universal Router via npm Source: https://github.com/kriasoft/universal-router/blob/main/README.md Instructions on how to install the Universal Router library using the npm package manager, saving it as a dependency in your project. ```bash npm install universal-router --save ``` -------------------------------- ### Initialize UniversalRouter with Routes and Options Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md Example demonstrating the creation of a UniversalRouter instance, defining a route object with an action, and configuring various options such as context, base URL, custom route resolution, and error handling. ```js import UniversalRouter from 'universal-router' const routes = { path: '/page', // string, array of strings, or a regular expression, optional name: 'page', // unique string, optional parent: null, // route object or null, automatically filled by the router children: [], // array of route objects, optional // function, optional action(context, params) { // action method should return anything except `null` or `undefined` to be resolved by router // otherwise router will throw `Page not found` error if all matched routes returned nothing return '

The Page

' }, // ... } const options = { context: { user: null }, baseUrl: '/base', resolveRoute(context, params) { if (typeof context.route.action === 'function') { return context.route.action(context, params) } return undefined }, errorHandler(error, context) { console.error(error) console.info(context) return error.status === 404 ? '

Page Not Found

' : '

Oops! Something went wrong

' } } const router = new UniversalRouter(routes, options) ``` -------------------------------- ### Basic Universal Router Usage Example Source: https://github.com/kriasoft/universal-router/blob/main/README.md Demonstrates how to define routes with actions and resolve a path using Universal Router. It shows both simple and nested routes, and how to access route parameters from the context object. ```js import UniversalRouter from 'https://esm.sh/universal-router' const routes = [ { path: '', // optional action: () => `

Home

`, }, { path: '/posts', action: () => console.log('checking child routes for /posts'), children: [ { path: '', // optional, matches both "/posts" and "/posts/" action: () => `

Posts

`, }, { path: '/:id', action: (context) => `

Post #${context.params.id}

`, }, ], }, ] const router = new UniversalRouter(routes) router.resolve('/posts').then((html) => { document.body.innerHTML = html // renders:

Posts

}) ``` -------------------------------- ### Basic HTML Hyperlink Examples Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md This snippet provides common examples of creating static HTML hyperlinks using string literals. While simple, this approach lacks dynamic URL generation capabilities based on route names. ```js const link1 = `Page` const link2 = `Profile` const link3 = `Search` const link4 = `Question` // etc. ``` -------------------------------- ### Integrating External Libraries for Query String Generation Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md This example demonstrates how to integrate an external library, such as 'qs', with the `stringifyQueryParams` option of `generateUrls`. This allows leveraging robust third-party solutions for complex query string serialization. ```js import qs from 'qs' generateUrls(router, { stringifyQueryParams: qs.stringify }) ``` -------------------------------- ### Using Universal Router in Synchronous Mode Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md This example illustrates how to initialize and use the synchronous Universal Router. The `resolve` method will directly return the result of the matching route action or throw an error, requiring all action functions to be synchronous. ```js const router = new UniversalRouterSync([ { path: '/one', action: () => 'Page One' }, { path: '/two', action: () => 'Page Two' } ]) const result = router.resolve({ pathname: '/one' }) console.log(result) // => Page One ``` -------------------------------- ### Setting Up and Using Universal Router URL Generation Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md This example shows how to import the `generateUrls` utility and use it to create a URL generation function. This function can then dynamically generate URLs based on defined route names and provided parameters, respecting a base URL if configured. ```js import UniversalRouter from 'universal-router' import generateUrls from 'universal-router/generateUrls' const routes = [ { name: 'users', path: '/users' }, { name: 'user', path: '/user/:username' } ] const router = new UniversalRouter(routes, { baseUrl: '/base' }) const url = generateUrls(router) url('users') // => '/base/users' url('user', { username: 'john' }) // => '/base/user/john' ``` -------------------------------- ### Redirect to Login for Authorization-Protected Pages Source: https://github.com/kriasoft/universal-router/blob/main/docs/redirects.md This example illustrates how to protect routes by checking user authentication status within the action method. If the user is not logged in (context.user is null), the router redirects them to a login page. ```JavaScript const router = new UniversalRouter([ { path: '/login', action() { return { content: '

Login

' } }, }, { path: '/admin', action(context) { if (!context.user) { return { redirect: '/login' } } return { content: '

Admin

' } }, }, ]) router .resolve({ pathname: '/admin', user: null, // <== is the user logged in? }) .then((page) => { if (page.redirect) { window.location = page.redirect } else { document.body.innerHTML = page.content } }) ``` -------------------------------- ### Implement Declarative Routing with Route Protection Source: https://github.com/kriasoft/universal-router/blob/main/docs/redirects.md This example shows a declarative way to define protected routes using a custom 'protected' flag on the route object. A custom 'resolveRoute' option in the UniversalRouter configuration then checks this flag and the user context to trigger redirects. ```JavaScript const routes = [ { path: '/login', content: '

Login

' }, { path: '/admin', protected: true, // <== protect current and all child routes children: [ { path: '', content: '

Admin: Home

' }, { path: '/users', content: '

Admin: Users

' }, { path: '/posts', content: '

Admin: Posts

' }, ], }, ] const router = new UniversalRouter(routes, { resolveRoute(context) { if (context.route.protected && !context.user) { return { redirect: '/login', from: context.pathname } // <== where the redirect come from? } if (context.route.content) { return { content: context.route.content } } return null }, }) router.resolve({ pathname: '/admin/users', user: null }).then((page) => { if (page.redirect) { console.log(`Redirect from ${page.from} to ${page.redirect}`) window.location = page.redirect } else { document.body.innerHTML = page.content } }) ``` -------------------------------- ### Configure Global Context in UniversalRouter Constructor (JS) Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md This example demonstrates how to specify custom context properties globally using the 'context' option in the UniversalRouter constructor. This allows for defining common data, like 'store' or 'user' objects, once for all routes. ```js const context = { store: {}, user: 'admin', // ... } const router = new UniversalRouter(route, { context }) ``` -------------------------------- ### Implement Middleware for Permissions Check in UniversalRouter (JS) Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md This example demonstrates using middleware for access control in UniversalRouter. It shows how an action function can return 'null' to skip nested routes if a condition (e.g., user not logged in) is not met, or return a value to deny access, or 'undefined' to proceed to child routes. ```js const middlewareRoute = { path: '/admin', action(context) { if (!context.user) { return null // route does not match (skip all /admin* routes) } if (context.user.role !== 'Admin') { return 'Access denied!' // return a page (for any /admin* urls) } return undefined // or `return context.next()` - try to match child routes }, children: [ /* admin routes here */ ], } ``` -------------------------------- ### Handle Server-Side Redirects with Node.js HTTP Source: https://github.com/kriasoft/universal-router/blob/main/docs/redirects.md This example shows how to implement server-side redirects using Node.js's built-in HTTP module. When a redirect is resolved by the router, the server responds with a 301 HTTP status code and sets the 'Location' header to the redirect target. ```JavaScript import http from 'http' import url from 'url' const server = http.createServer(async (req, res) => { const location = url.parse(req.url) const page = await router.resolve(location.pathname) if (page.redirect) { res.writeHead(301, { Location: page.redirect }) res.end() } else { res.write(`${page.content}`) res.end() } }) server.listen(8080) ``` -------------------------------- ### Customizing URI Encoding in URL Generation Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md This example illustrates how to provide a custom `encode` option to `generateUrls` to override the default `encodeURIComponent` behavior. This allows for specific handling of URI path segments, such as preventing encoding for certain characters. ```js const prettyUrl = generateUrls(router, { encode: (value, token) => value }) url('user', { username: ':/' }) // => '/base/user/%3A%2F' prettyUrl('user', { username: ':/' }) // => '/base/user/:/' ``` -------------------------------- ### Access Named URL Parameters via Destructuring in UniversalRouter (JS) Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md This example shows an alternative method to access named URL parameters in UniversalRouter. Parameters are destructured directly from the second argument of the action method, providing a cleaner way to use them. ```js const router = new UniversalRouter({ path: '/hello/:username', action: (ctx, { username }) => `Welcome, ${username}!`, }) router .resolve({ pathname: '/hello/john' }) .then((result) => console.log(result)) // => Welcome, john! ``` -------------------------------- ### Handle Asynchronous Routes with ES6 Promises in UniversalRouter (JS) Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md This example demonstrates handling asynchronous route actions using traditional ES6 Promises in UniversalRouter. It shows how to chain '.then()' calls to fetch and process data from an API, returning a resolved value. ```js const route = { path: '/hello/:username', action({ params }) { return fetch(`/api/users/${params.username}`) .then((resp) => resp.json()) .then((user) => user && `Welcome, ${user.displayName}!`) }, } ``` -------------------------------- ### Run Unit Tests with Vitest Source: https://github.com/kriasoft/universal-router/blob/main/tools/README.md This command executes the project's unit tests using Vitest, a fast and modern test framework. Running tests ensures that individual components of the application function correctly and helps catch regressions early in the development cycle. ```bash npm run test ``` -------------------------------- ### Compile JavaScript Library with npm Source: https://github.com/kriasoft/universal-router/blob/main/tools/README.md This command compiles the project's JavaScript library, typically transpiling source code and bundling it into a distributable format. The output is placed in the './dist' folder, which is a standard build step for many JavaScript projects. ```bash npm run build ``` -------------------------------- ### UniversalRouter Constructor API Reference Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md Details the `UniversalRouter` constructor, its parameters, and available options for configuring routing behavior, context, and error handling. ```APIDOC UniversalRouter(routes, options): routes: object | array - A plain JavaScript object or array of objects defining the application's routes. path: string | array | RegExp - The URL path to match (optional). name: string - A unique identifier for the route (optional). parent: object | null - Reference to the parent route object (automatically filled). children: array - An array of child route objects (optional). action(context, params): function - A function that returns any data (except null/undefined) when the route matches. options: object - Configuration options for the router (optional). context: object - An object containing data passed to the resolveRoute function. baseUrl: string - The base URL for the application (defaults to ''). resolveRoute(context, params): function - Custom logic for route handling; defaults to calling the matched route's action. errorHandler(error, context): function - Global error handling function called for unfound routes or errors. ``` -------------------------------- ### Format JavaScript Code with Prettier Source: https://github.com/kriasoft/universal-router/blob/main/tools/README.md This command runs Prettier to automatically format the project's code, ensuring consistent styling across the entire codebase. Prettier helps reduce bikeshedding over code style and significantly improves readability and maintainability. ```bash npm run format ``` -------------------------------- ### Lint JavaScript Code with ESLint Source: https://github.com/kriasoft/universal-router/blob/main/tools/README.md This command executes ESLint to identify and report problematic patterns found in the JavaScript code. ESLint helps maintain code quality and consistency by enforcing coding standards and catching potential errors, improving overall code health. ```bash npm run lint ``` -------------------------------- ### Implement Basic Redirect with Universal Router Source: https://github.com/kriasoft/universal-router/blob/main/docs/redirects.md This snippet demonstrates the fundamental way to perform a redirect by returning an object with a 'redirect' property from a route's action method. On the client side, the resolved page object is checked for this property to trigger the actual browser redirect. ```JavaScript import UniversalRouter from 'universal-router' const router = new UniversalRouter([ { path: '/redirect', action() { return { redirect: '/target' } // <== request a redirect }, }, { path: '/target', action() { return { content: '

Content

' } }, }, ]) router.resolve('/redirect').then((page) => { if (page.redirect) { window.location = page.redirect // <== actual redirect here } else { document.body.innerHTML = page.content } }) ``` -------------------------------- ### Implement Basic Middleware in UniversalRouter (JS) Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md This snippet illustrates the use of middleware in UniversalRouter, where an action function calls 'context.next()' to pass control to child routes. It demonstrates how middleware can wrap the execution of child routes, performing actions before and after. ```js const router = new UniversalRouter({ path: '', // optional async action({ next }) { console.log('middleware: start') const child = await next() console.log('middleware: end') return child }, children: [ { path: '/hello', action() { console.log('route: return a result') return 'Hello, world!' }, }, ], }) router.resolve({ pathname: '/hello' }) // Prints: // middleware: start // route: return a result // middleware: end ``` -------------------------------- ### Handle Asynchronous Routes with Async/Await in UniversalRouter (JS) Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md This snippet shows how to implement asynchronous route actions using 'async'/'await' syntax in UniversalRouter. It demonstrates fetching user data from an API and returning a dynamic response based on the fetched information. ```js const router = new UniversalRouter({ path: '/hello/:username', async action({ params }) { const resp = await fetch(`/api/users/${params.username}`) const user = await resp.json() if (user) return `Welcome, ${user.displayName}!` }, }) router .resolve({ pathname: '/hello/john' }) .then((result) => console.log(result)) // => Welcome, John Brown! ``` -------------------------------- ### Importing Universal Router's Synchronous Version Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md This snippet demonstrates how to import the synchronous version of Universal Router by changing the import path from 'universal-router' to 'universal-router/sync'. This allows for synchronous route resolution without Promise support. ```diff -import UniversalRouter from 'universal-router' +import UniversalRouterSync from 'universal-router/sync' ``` -------------------------------- ### Resolve Pathname with UniversalRouter Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md Demonstrates how to use the `router.resolve` method to match a given pathname against defined routes and retrieve the result of the matched route's action. ```js const router = new UniversalRouter([ { path: '/one', action: () => 'Page One' }, { path: '/two', action: () => 'Page Two' } ]) router.resolve({ pathname: '/one' }).then((result) => console.log(result)) // => Page One ``` -------------------------------- ### router.resolve Method API Reference Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md Documents the `router.resolve` method, its parameters, and return type, which is used to traverse routes and find a match for a given URL path. ```APIDOC router.resolve({ pathname, ...context }): Promise pathname: string - The URL path string to resolve. ...context: object - Additional context data to pass to the resolution process. Returns: Promise - A promise that resolves with the result of the matched route's action. ``` -------------------------------- ### Protect Multiple Routes Using Middleware Redirect Source: https://github.com/kriasoft/universal-router/blob/main/docs/redirects.md This snippet demonstrates using a middleware approach to protect a group of child routes. The parent route's action checks for user authentication; if unauthorized, it redirects, otherwise, it calls context.next() to proceed to child routes. ```JavaScript const adminRoutes = { path: '/admin', action(context) { if (!context.user) { return { redirect: '/login' } // stop and redirect } return context.next() // go to children }, children: [ { path: '', action: () => ({ content: '

Admin: Home

' }) }, { path: '/users', action: () => ({ content: '

Admin: Users

' }) }, { path: '/posts', action: () => ({ content: '

Admin: Posts

' }) }, ], } ``` -------------------------------- ### UniversalRouter Context Object Properties (APIDOC) Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md This section details the standard properties automatically added to the 'context' object by UniversalRouter before being passed to 'resolveRoute' functions. These properties provide essential information about the current router instance, matched route, and request details. ```APIDOC context: router: Current router instance. route: Matched route object. next: Middleware style function which can continue resolving. pathname: URL which was transmitted to router.resolve(). baseUrl: Base URL path relative to the path of the current route. path: Matched path. params: Matched path params. ``` -------------------------------- ### Catch-all Nested Routes with Empty Children Array Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md Shows how setting the `children` property to an empty array on a parent route can act as a catch-all, resolving any sub-paths to the parent's action. ```js const router = new UniversalRouter({ path: '/admin', children: [], action: () => 'Admin Page' }) router .resolve({ pathname: '/admin/users/john' }) .then((result) => console.log(result)) // => Admin Page router .resolve({ pathname: '/admin/some/other/page' }) .then((result) => console.log(result)) // => Admin Page ``` -------------------------------- ### Generating URLs for Dynamically Added Routes Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md This snippet demonstrates that the URL generation function created with `generateUrls` automatically supports routes that are added to the router's configuration at runtime, providing flexibility for dynamic application structures. ```js routes.children.push({ path: '/world', name: 'hello' }) url('hello') // => '/base/world' ``` -------------------------------- ### Capture Named URL Parameters in UniversalRouter (JS) Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md This snippet demonstrates how to define routes with named URL parameters using UniversalRouter. The captured parameter, 'username', is then accessed via 'context.params' within the action function to generate a dynamic welcome message. ```js const router = new UniversalRouter({ path: '/hello/:username', action: (context) => `Welcome, ${context.params.username}!`, }) router .resolve({ pathname: '/hello/john' }) .then((result) => console.log(result)) // => Welcome, john! ``` -------------------------------- ### Perform Client-Side Redirects Using History API Source: https://github.com/kriasoft/universal-router/blob/main/docs/redirects.md This snippet demonstrates how to achieve client-side redirects without a full page reload by utilizing the browser's History API. Instead of assigning to window.location, it uses window.history.pushState to change the URL and state. ```JavaScript router.resolve('/redirect').then((page) => { if (page.redirect) { const state = { from: page.from } window.history.pushState(state, '', page.redirect) } else { document.body.innerHTML = page.content } }) ``` -------------------------------- ### Pass Custom Data to UniversalRouter Context (JS) Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md This snippet illustrates how to pass arbitrary data, such as a 'user' property, to the 'router.resolve()' method. This data becomes available within the 'action' function via the 'context' object, allowing for dynamic content generation. ```js const router = new UniversalRouter({ path: '/hello', action(context) { return `Welcome, ${context.user}!` }, }) router .resolve({ pathname: '/hello', user: 'admin' }) .then((result) => console.log(result)) // => Welcome, admin! ``` -------------------------------- ### Customizing Query String Generation in URLs Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md This snippet shows how to use the `stringifyQueryParams` option with `generateUrls` to provide a custom function for converting unknown route parameters into a URL query string. This allows for flexible query string formatting. ```js const urlWithQueryString = generateUrls(router, { stringifyQueryParams: (params) => new URLSearchParams(params).toString() }) const params = { username: 'John', busy: '1' } url('user', params) // => /base/user/John urlWithQueryString('user', params) // => /base/user/John?busy=1 ``` -------------------------------- ### Define Nested Routes with UniversalRouter Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md Illustrates how to structure routes hierarchically using the `children` property, allowing for complex URL patterns and organization of application sections. ```js const router = new UniversalRouter({ path: '/admin', children: [ { path: '', // www.example.com/admin action: () => 'Admin Page' }, { path: '/users', children: [ { path: '', // www.example.com/admin/users action: () => 'User List' }, { path: '/:username', // www.example.com/admin/users/john action: () => 'User Profile' } ] } ] }) router .resolve({ pathname: '/admin/users/john' }) .then((result) => console.log(result)) // => User Profile ``` -------------------------------- ### Generating URLs with Non-Unique Route Names and Separators Source: https://github.com/kriasoft/universal-router/blob/main/docs/api.md This snippet explains how to use the `uniqueRouteNameSep` option to handle non-unique route names across different branches of nested routes. The router automatically generates unique names by prepending parent route names with the specified separator. ```js const router = new UniversalRouter([ { name: 'users', path: '/users', children: [{ name: 'list', path: '/list' }] }, { name: 'pages', path: '/pages', children: [{ name: 'list', path: '/list' }] } ]) const url = generateUrls(router, { uniqueRouteNameSep: '.' }) url('users.list') // => /users/list url('pages.list') // => /pages/list ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.