routerino 1.1.10 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +184 -111
- package/build-static.js +407 -0
- package/dist/routerino.js +181 -118
- package/dist/routerino.umd.cjs +1 -1
- package/package.json +28 -4
- package/types/routerino.d.ts +36 -4
package/README.md
CHANGED
|
@@ -2,13 +2,41 @@
|
|
|
2
2
|
|
|
3
3
|
> A lightweight, SEO-optimized React router for modern websites and applications
|
|
4
4
|
|
|
5
|
-
Routerino is a zero-dependency router
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
Routerino is a zero-dependency router for React (17/18/19) designed for optimal SEO performance in client-side rendered applications. Built for modern web architectures like JAMStack applications and Vite-powered React sites, it provides route & meta tag management, sitemap generation, and static site generation or [prerender](https://github.com/prerender/prerender) support to ensure your React applications are fully discoverable by search engines.
|
|
6
|
+
|
|
7
|
+
## Why Routerino?
|
|
8
|
+
|
|
9
|
+
- **SEO-First Design**: Automatic meta tag management, sitemap generation, and prerender support ensure maximum search engine visibility
|
|
10
|
+
- **Zero Dependencies**: Keeps bundle size minimal and reduces supply-chain vulnerabilities
|
|
11
|
+
- **Simple API**: No special `Link` components required - use standard HTML anchors and navigate programmatically with standard browser APIs
|
|
12
|
+
- **Static Site Generation**: Build-tool agnostic static HTML generation for improved performance and SEO
|
|
13
|
+
- **Production Ready**: Includes Docker-based prerender server for easy deployments
|
|
14
|
+
- **Single File Core**: The entire routing logic fits in one file (~420 lines), making it easy to understand and customize
|
|
15
|
+
|
|
16
|
+
## Table of Contents
|
|
17
|
+
|
|
18
|
+
- [Features](#features)
|
|
19
|
+
- [Installation](#installation)
|
|
20
|
+
- [Usage](#usage)
|
|
21
|
+
- [Props](#props-arguments)
|
|
22
|
+
- [Get route parameters](#get-route-parameters-and-the-current-route-and-updating-head-tags)
|
|
23
|
+
- [updateHeadTag](#updateheadtag)
|
|
24
|
+
- [Best Practices](#routerino-best-practices)
|
|
25
|
+
- [Generating a Sitemap](#generating-a-sitemap-from-routes)
|
|
26
|
+
- [Static Site Generation](#static-site-generation)
|
|
27
|
+
- [Deployment Guides](#deployment-guides)
|
|
28
|
+
- [Prerender Server (Docker)](#prerender-server-docker)
|
|
29
|
+
- [How-to Guides & Examples](#how-to-guides--example-code)
|
|
30
|
+
- [Starting a New Project](#starting-a-new-react-project-with-routerino)
|
|
31
|
+
- [Full React Example](#full-react-example)
|
|
32
|
+
- [Basic Example](#basic-example)
|
|
33
|
+
- [ErrorBoundary Component](#errorboundary-component)
|
|
34
|
+
- [Vendoring Routerino](#vendoring-routerino)
|
|
35
|
+
- [Additional Resources](#additional-resources)
|
|
36
|
+
- [Contributions](#contributions)
|
|
37
|
+
- [License](#license)
|
|
38
|
+
|
|
39
|
+
## Quick Start
|
|
12
40
|
|
|
13
41
|
```jsx
|
|
14
42
|
<Routerino
|
|
@@ -36,36 +64,28 @@ Here's a quick example of what using Routerino looks like:
|
|
|
36
64
|
/>
|
|
37
65
|
```
|
|
38
66
|
|
|
39
|
-
|
|
67
|
+
This simple configuration automatically handles routing, meta tags, and SEO optimization for your React application.
|
|
40
68
|
|
|
41
69
|
## Features
|
|
42
70
|
|
|
43
|
-
Routerino empowers developers to define and manage routing and SEO concerns in one centralized location. This approach eliminates duplication when creating sitemaps and setting page metadata, such as descriptions or open-graph tags. The core of Routerino fits in a single file, making it [easy to vendor](#vendoring-routerino) if that suits your needs.
|
|
44
|
-
|
|
45
|
-
Key capabilities:
|
|
46
|
-
|
|
47
71
|
- Routing
|
|
48
|
-
|
|
49
|
-
- Easy integration of simple routing for your React app (supports React v18, older versions have not yet been tested)
|
|
72
|
+
- Easy integration of simple routing for your React app (supports React versions 17, 18, and 19)
|
|
50
73
|
- Zero dependencies for lighter, more maintainable projects
|
|
51
74
|
- No special link components required, works great for Markdown-based pages and semantic HTML
|
|
52
75
|
|
|
53
76
|
- SEO Optimization
|
|
54
|
-
|
|
55
77
|
- Configure title, description, and image for each route
|
|
56
78
|
- Set `<head>` tags for any route (either directly in your routes config, or dynamically after rendering)
|
|
57
79
|
- Set a site-wide name to be included with page titles
|
|
58
80
|
- Automatically generate and maintain an up-to-date `sitemap.xml` from your routes
|
|
81
|
+
- Generate static HTML files for each route with proper meta tags
|
|
59
82
|
- Implement SEO best practices out-of-the-box
|
|
60
83
|
- Optimize for Googlebot with pre-rendering support
|
|
61
84
|
|
|
62
85
|
- Enhanced User Experience
|
|
63
|
-
|
|
64
86
|
- Support for sharing and social preview metadata
|
|
65
87
|
- Snappy page transitions with automatic scroll reset, eliminating the jarring experience of landing mid-page when navigating
|
|
66
88
|
|
|
67
|
-
Routerino is designed to work with modern browsers and has been tested with the latest versions of Chrome, Firefox, Safari, and Edge.
|
|
68
|
-
|
|
69
89
|
## Installation
|
|
70
90
|
|
|
71
91
|
Ensure that you have React and React DOM installed in your project as peer dependencies. To add as a dev dependency:
|
|
@@ -77,9 +97,10 @@ npm i routerino -D
|
|
|
77
97
|
### Compatibility
|
|
78
98
|
|
|
79
99
|
Routerino supports:
|
|
100
|
+
|
|
80
101
|
- **React 17, 18, and 19** - All versions are tested and supported
|
|
81
|
-
- **Preact** - Compatible via `@preact/compat`
|
|
82
|
-
- **Node.js 18+** - Tested on Node.js 18, 20, and
|
|
102
|
+
- **Preact** - Compatible via `@preact/compat` (needs verification)
|
|
103
|
+
- **Node.js 18+** - Tested on Node.js 18, 20, 22, and 24. Could be used on earlier versions if we don't run tests.
|
|
83
104
|
|
|
84
105
|
## Usage
|
|
85
106
|
|
|
@@ -99,7 +120,7 @@ Here's a quick example of using Routerino in your React application:
|
|
|
99
120
|
/>
|
|
100
121
|
```
|
|
101
122
|
|
|
102
|
-
Links are just regular HTML anchor tags. No need to use special `<Link>` components and you can handle styling however you wish. For example: `<a href="/some-page
|
|
123
|
+
Links are just regular HTML anchor tags. No need to use special `<Link>` components and you can handle styling however you wish. For example: `<a href="/some-page/">a link</a>`
|
|
103
124
|
|
|
104
125
|
See [props](#props-arguments) for full explanations and [example code](#how-to-guides--example-code) for more complete code samples.
|
|
105
126
|
|
|
@@ -145,7 +166,7 @@ See [RouteConfig props](#routeconfig-props) for more details. At a minimum a pat
|
|
|
145
166
|
|
|
146
167
|
##### `separator`: string;
|
|
147
168
|
|
|
148
|
-
A string to separate the page title from the site title. The default is
|
|
169
|
+
A string to separate the page title from the site title. The default is `" | "` (a pipe character w/space around). Set this to customize the separator.
|
|
149
170
|
|
|
150
171
|
##### `notFoundTemplate`: element;
|
|
151
172
|
|
|
@@ -412,11 +433,84 @@ Add `routerino-build-sitemap` to your build command to update automatically on e
|
|
|
412
433
|
|
|
413
434
|
Example package.json build script: `"build": "vite build && routerino-build-sitemap routeFilePath=src/routes.jsx hostname=https://example.com outputDir=dist",`
|
|
414
435
|
|
|
436
|
+
## Static Site Generation
|
|
437
|
+
|
|
438
|
+
Routerino includes a build-tool agnostic static site generator that creates HTML files for each route, improving SEO and initial page load performance.
|
|
439
|
+
|
|
440
|
+
### How It Works
|
|
441
|
+
|
|
442
|
+
The `routerino-build-static` command is a **post-build step** that works with ANY build tool (Vite, Webpack, Parcel, etc.):
|
|
443
|
+
|
|
444
|
+
1. **First**: Build your app with your preferred build tool (`npm run build`)
|
|
445
|
+
2. **Then**: Run `routerino-build-static` to generate static HTML files
|
|
446
|
+
|
|
447
|
+
```sh
|
|
448
|
+
# After your build completes (creates dist/index.html with bundled JS/CSS):
|
|
449
|
+
routerino-build-static routesFile=src/routes.jsx outputDir=dist template=dist/index.html baseUrl=https://example.com
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
**Parameters:**
|
|
453
|
+
|
|
454
|
+
- `routesFile` - Path to your routes configuration file (supports .js, .jsx, .ts, .tsx)
|
|
455
|
+
- `outputDir` - Directory where static HTML files will be generated (usually your build output)
|
|
456
|
+
- `template` - Your **built** HTML file with bundled assets (e.g., dist/index.html)
|
|
457
|
+
- `baseUrl` - Base URL for meta tags (optional but recommended for SEO)
|
|
458
|
+
|
|
459
|
+
### Build Tool Examples
|
|
460
|
+
|
|
461
|
+
Works with any build tool:
|
|
462
|
+
|
|
463
|
+
```json
|
|
464
|
+
// Vite
|
|
465
|
+
"build": "vite build && routerino-build-static routesFile=src/routes.js outputDir=dist template=dist/index.html"
|
|
466
|
+
|
|
467
|
+
// Webpack
|
|
468
|
+
"build": "webpack && routerino-build-static routesFile=src/routes.js outputDir=build template=build/index.html"
|
|
469
|
+
|
|
470
|
+
// Parcel
|
|
471
|
+
"build": "parcel build index.html && routerino-build-static routesFile=src/routes.js outputDir=dist template=dist/index.html"
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
### What Gets Generated
|
|
475
|
+
|
|
476
|
+
The static build process will:
|
|
477
|
+
|
|
478
|
+
- Generate an HTML file for each non-dynamic route (routes with `:param` are skipped)
|
|
479
|
+
- Apply route-specific meta tags (title, description, og:tags, custom tags)
|
|
480
|
+
- Add proper `data-route` attributes for client-side hydration
|
|
481
|
+
- Preserve your existing HTML structure and assets
|
|
482
|
+
|
|
483
|
+
### Example Output
|
|
484
|
+
|
|
485
|
+
For a route configuration like:
|
|
486
|
+
|
|
487
|
+
```javascript
|
|
488
|
+
{
|
|
489
|
+
path: '/about',
|
|
490
|
+
title: 'About Us',
|
|
491
|
+
description: 'Learn more about our company',
|
|
492
|
+
imageUrl: 'https://example.com/about-og.jpg'
|
|
493
|
+
}
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
The generated `/about.html` will include:
|
|
497
|
+
|
|
498
|
+
```html
|
|
499
|
+
<title>About Us</title>
|
|
500
|
+
<meta name="description" content="Learn more about our company" />
|
|
501
|
+
<meta property="og:title" content="About Us" />
|
|
502
|
+
<meta property="og:description" content="Learn more about our company" />
|
|
503
|
+
<meta property="og:image" content="https://example.com/about-og.jpg" />
|
|
504
|
+
<meta property="og:url" content="https://example.com/about" />
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
This provides excellent SEO while maintaining the benefits of a React SPA.
|
|
508
|
+
|
|
415
509
|
## How-to Guides & Example Code
|
|
416
510
|
|
|
417
511
|
1. [Starting a New React Project with Routerino](#starting-a-new-react-project-with-routerino)
|
|
418
|
-
2. [
|
|
419
|
-
3. [
|
|
512
|
+
2. [Full React Example](#full-react-example)
|
|
513
|
+
3. [Basic Example](#basic-example)
|
|
420
514
|
|
|
421
515
|
### Starting a New React Project with Routerino
|
|
422
516
|
|
|
@@ -464,40 +558,15 @@ This command will install the latest version of Routerino and save it to your `p
|
|
|
464
558
|
|
|
465
559
|
With these steps, you'll have a new React project set up with Vite as the build tool and Routerino installed as a development dependency. You can now start building your application with React & Routerino.
|
|
466
560
|
|
|
467
|
-
###
|
|
561
|
+
### Full React Example
|
|
468
562
|
|
|
469
|
-
|
|
563
|
+
This example includes the full React configuration. It might take the place of `src/main.jsx` or an `index.js` file.
|
|
470
564
|
|
|
471
565
|
```jsx
|
|
472
566
|
import React from "react";
|
|
567
|
+
import { render } from "react-dom";
|
|
473
568
|
import Routerino from "routerino";
|
|
474
569
|
|
|
475
|
-
// example pages
|
|
476
|
-
import HomePage from "./HomePage";
|
|
477
|
-
import AboutPage from "./AboutPage";
|
|
478
|
-
import ContactPage from "./ContactPage";
|
|
479
|
-
|
|
480
|
-
const routes = [
|
|
481
|
-
{
|
|
482
|
-
path: "/",
|
|
483
|
-
element: <HomePage />,
|
|
484
|
-
title: "Home",
|
|
485
|
-
description: "Welcome to my website!",
|
|
486
|
-
},
|
|
487
|
-
{
|
|
488
|
-
path: "/about/",
|
|
489
|
-
element: <AboutPage />,
|
|
490
|
-
title: "About",
|
|
491
|
-
description: "Learn more about us.",
|
|
492
|
-
},
|
|
493
|
-
{
|
|
494
|
-
path: "/contact/",
|
|
495
|
-
element: <ContactPage />,
|
|
496
|
-
title: "Contact",
|
|
497
|
-
description: "Get in touch with us.",
|
|
498
|
-
},
|
|
499
|
-
];
|
|
500
|
-
|
|
501
570
|
const App = () => (
|
|
502
571
|
<main>
|
|
503
572
|
<nav>
|
|
@@ -505,10 +574,37 @@ const App = () => (
|
|
|
505
574
|
</nav>
|
|
506
575
|
|
|
507
576
|
<Routerino
|
|
508
|
-
title="
|
|
509
|
-
routes={routes}
|
|
577
|
+
title="Example.com"
|
|
510
578
|
notFoundTitle="Sorry, but this page does not exist."
|
|
511
579
|
errorTitle="Yikes! Something went wrong."
|
|
580
|
+
routes={[
|
|
581
|
+
{
|
|
582
|
+
path: "/",
|
|
583
|
+
element: <p>Welcome to Home</p>,
|
|
584
|
+
title: "Home",
|
|
585
|
+
description: "Welcome to my website!",
|
|
586
|
+
},
|
|
587
|
+
{
|
|
588
|
+
path: "/about/",
|
|
589
|
+
element: <p>About us...</p>,
|
|
590
|
+
title: "About",
|
|
591
|
+
description: "Learn more about us.",
|
|
592
|
+
},
|
|
593
|
+
{
|
|
594
|
+
path: "/contact/",
|
|
595
|
+
element: (
|
|
596
|
+
<div>
|
|
597
|
+
<h1>Contact Us</h1>
|
|
598
|
+
<p>
|
|
599
|
+
Please <a href="mailto:user@example.com">send us an email</a> at
|
|
600
|
+
user@example.com
|
|
601
|
+
</p>
|
|
602
|
+
</div>
|
|
603
|
+
),
|
|
604
|
+
title: "Contact",
|
|
605
|
+
description: "Get in touch with us.",
|
|
606
|
+
},
|
|
607
|
+
]}
|
|
512
608
|
/>
|
|
513
609
|
|
|
514
610
|
<footer>
|
|
@@ -520,72 +616,49 @@ const App = () => (
|
|
|
520
616
|
</main>
|
|
521
617
|
);
|
|
522
618
|
|
|
523
|
-
|
|
619
|
+
render(<App />, document.getElementById("root"));
|
|
524
620
|
```
|
|
525
621
|
|
|
526
|
-
|
|
622
|
+
## ErrorBoundary Component
|
|
527
623
|
|
|
528
|
-
|
|
624
|
+
Routerino exports an `ErrorBoundary` component that you can use in your own applications to catch and handle React component errors gracefully. Fun fact: error boundary components are one of the last cases that still require using a React Class! Since this library aims to include everything you need to build a multiple page React SPA, and enable users to be able to know which component had an issue without confusing it with a Routerino bug.
|
|
625
|
+
|
|
626
|
+
### Import
|
|
529
627
|
|
|
530
628
|
```jsx
|
|
531
|
-
import
|
|
532
|
-
|
|
533
|
-
import Routerino from "routerino";
|
|
629
|
+
import { ErrorBoundary } from "routerino";
|
|
630
|
+
```
|
|
534
631
|
|
|
535
|
-
|
|
536
|
-
const routes = [
|
|
537
|
-
{
|
|
538
|
-
path: "/",
|
|
539
|
-
element: <p>Welcome to Home</p>,
|
|
540
|
-
title: "Home",
|
|
541
|
-
description: "Welcome to my website!",
|
|
542
|
-
},
|
|
543
|
-
{
|
|
544
|
-
path: "/about/",
|
|
545
|
-
element: <p>About us...</p>,
|
|
546
|
-
title: "About",
|
|
547
|
-
description: "Learn more about us.",
|
|
548
|
-
},
|
|
549
|
-
{
|
|
550
|
-
path: "/contact/",
|
|
551
|
-
element: (
|
|
552
|
-
<div>
|
|
553
|
-
<h1>Contact Us</h1>
|
|
554
|
-
<p>
|
|
555
|
-
Please <a href="mailto:user@example.com">send us an email</a> at
|
|
556
|
-
user@example.com
|
|
557
|
-
</p>
|
|
558
|
-
</div>
|
|
559
|
-
),
|
|
560
|
-
title: "Contact",
|
|
561
|
-
description: "Get in touch with us.",
|
|
562
|
-
},
|
|
563
|
-
];
|
|
632
|
+
### Usage
|
|
564
633
|
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
634
|
+
```jsx
|
|
635
|
+
<ErrorBoundary
|
|
636
|
+
fallback={<div>Something went wrong. Please try again.</div>}
|
|
637
|
+
errorTitleString="Error | My Application"
|
|
638
|
+
usePrerenderTags={true}
|
|
639
|
+
>
|
|
640
|
+
<MyComponent />
|
|
641
|
+
</ErrorBoundary>
|
|
642
|
+
```
|
|
570
643
|
|
|
571
|
-
|
|
572
|
-
{...{
|
|
573
|
-
title,
|
|
574
|
-
routes,
|
|
575
|
-
}}
|
|
576
|
-
/>
|
|
644
|
+
### Props
|
|
577
645
|
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
</main>
|
|
585
|
-
);
|
|
646
|
+
| Prop | Type | Required | Description |
|
|
647
|
+
| ------------------ | ----------- | -------- | ---------------------------------------------------- |
|
|
648
|
+
| `children` | `ReactNode` | No | The child components to render when there's no error |
|
|
649
|
+
| `fallback` | `ReactNode` | No | The UI to display when an error is caught |
|
|
650
|
+
| `errorTitleString` | `string` | Yes | The document title to set when an error occurs |
|
|
651
|
+
| `usePrerenderTags` | `boolean` | No | Whether to set prerender meta tag (status code 500) |
|
|
586
652
|
|
|
587
|
-
|
|
588
|
-
|
|
653
|
+
### Features
|
|
654
|
+
|
|
655
|
+
- Catches JavaScript errors in child component tree
|
|
656
|
+
- Displays fallback UI instead of white screen
|
|
657
|
+
- Sets document title on error
|
|
658
|
+
- Logs errors to console for debugging
|
|
659
|
+
- Optionally sets prerender status code for SEO
|
|
660
|
+
|
|
661
|
+
This is the same error boundary used internally by Routerino to protect your route components from crashing the entire application.
|
|
589
662
|
|
|
590
663
|
## Vendoring Routerino
|
|
591
664
|
|
|
@@ -624,7 +697,7 @@ By vendoring Routerino, you have full control over the code and can make any nec
|
|
|
624
697
|
|
|
625
698
|
## Additional Resources
|
|
626
699
|
|
|
627
|
-
|
|
700
|
+
Here are some sources for further reading on SEO best-practices.
|
|
628
701
|
|
|
629
702
|
- [Apple's best practices for link previews](https://developer.apple.com/library/archive/technotes/tn2444/_index.html)
|
|
630
703
|
- [Use Open Graph tags](https://ahrefs.com/blog/open-graph-meta-tags/)
|