---
title: 'Routex'
excerpt: 'An easy, configurable client-side redirection plugin for VitePress.'
date: 2025-06-22
categories: open-source, web
featureImage: '/images/routex.webp'

prev:
  text: 'ChatGPT - Bulk Actions'
  link: '/blog/chatgpt-bulk-actions'

next:
  text: 'Appwrite: Import CSV'
  link: '/blog/appwrite-import-csv'
---

For a while now, I've found myself in one of those situations where a simple problem turns into a `"might as well build
something"` moment.

On my main server, this is easy—because I run a buildscript during deployment that adds all the redirects from a json
file to `.htaccess` and call it a day.

But here's the thing: I also use services like [Render.com](https://render.com)
and [Appwrite Sites](https://appwrite.io/products/sites) for PR previews. And guess what? Those redirects don't work
there because the SSGs don't have that capability and the platform don't always support these.

So I had a choice: manually create redirect HTML files just for these platforms, or spend some time to build a proper
solution. I obviously chose the latter 😄

---

### The real problem

Static sites are great until you need to handle redirects. Most providers—especially the free ones—either don't support
server-side redirects or make them unnecessarily complicated. And when you're using multiple hosting services for
different purposes (like I do with preview environments), maintaining redirects can be a hassle.

I looked around for existing solutions but the one I found was managing the redirects via `enhanceApp` hook. If you
don't know, redirections from that hook can briefly show a `404`. Ehhh, big NO for me.

**`VitePress`** despite being fantastic, didn't have a clean way to handle this.

---

### Enter **`Routex`**

What I wanted was simple: define redirects in my VitePress config and have everything else handled automatically. No
manual HTML files, no server configuration, no headaches.

That's exactly what **`Routex`** does:

```javascript
// .vitepress/config.ts
import { routex } from 'routex';

export default defineConfig({
    /* other existing config */

    vite: {
        plugins: [
            routex({
                '/cls': '/blog/chrome-shortcuts',
                '/appexpress': '/blog/appexpress',
                '/ghosler': '/blog/ghosler'
            })
        ]
    }
});
```

And that's it. The plugin handles the rest, generates redirect pages during build, injects client-side navigation
scripts, and even adds fallbacks for when JavaScript is disabled.

---

### How it actually works

The plugin does three things:

1. **Client-side interception**: When someone navigates to an old URL, JavaScript catches it and redirects instantly
2. **Static page generation**: Creates actual HTML files for each redirect during build time
3. **Fallback support**: Uses meta refresh tags so redirects work even without JavaScript

Note: When running `pnpm dev`, the plugin manages redirects on the fly, so changes are reflected immediately as you
develop.

This means it works everywhere: GitHub Pages, Netlify, Vercel, my PHP server, Render previews, Appwrite hosting, you
name it.

---

### The validation bit

One thing I added was the **redirect validation**. It checks for:

- Dead links
- Self-references (A → A)
- Circular redirects (A → B → A)
- Conflicts with existing pages to not override them

Saves you from deploying broken redirects and then wondering why your site is acting weird.

---

### Advanced options

For more complex scenarios, you can customize the behavior:

```javascript
routex({
    rules: {
        '/cls': '/blog/chrome-shortcuts',
        '/appexpress': '/blog/appexpress',
        '/ghosler': '/blog/ghosler',
    },
    options: {
        redirectDelay: 2,        // Delay in seconds (default: 0)
        addCanonical: true,      // Add canonical link tags (default: false)
        addNoIndexMeta: true,    // Add noindex meta tag (default: false)
        template: './template.html',  // Custom template path or raw string
        overrideExisting: false, // Allow overriding existing pages (default: false)
        ignoreDeadLinks: false   // Skip validation for missing destinations (default: false)
    }
});
```

---

### Real usage

I've started using this on my own site for PR previews, and it's been working great. The plugin generates clean
redirect pages that blend with your site's design, and the validation catches issues before they hit production.

It's particularly useful when migrating from other platforms or when you need to consolidate or test content without
breaking existing links.

---

So that's **Routex**, born from not wanting to manually do stuff with files. It's available as
`@itznotabug/routex` on npm, and the code is up
on [https://github.com/ItzNotABug/routex](https://github.com/ItzNotABug/routex).

If you're dealing with VitePress redirects and don't want to mess with server configs or manual HTML files, give it a
shot. It might save you some time!