# How Route Parameter Validation Works with SLUG_REGEX in SXO

> Learn how SXO validates dynamic route parameters using SLUG_REGEX. Discover the compile-time and runtime checks that ensure correct URL patterns and prevent errors.

- Repository: [Víctor García/sxo](https://github.com/gc-victor/sxo)
- Tags: how-to-guide
- Published: 2026-03-02

---

**SXO validates dynamic route parameters through a two-stage process: compile-time name validation via `validateRoutePattern()` and runtime value validation against `SLUG_REGEX`, returning `{ invalid: true }` to trigger a 404 when values fail the regex test.**

Route parameter validation in the SXO framework ensures that dynamic segments like `[slug]` in `/blog/[slug]` are both properly defined at build time and safely handled during request processing. The system employs `SLUG_REGEX` as a security boundary to prevent malformed or malicious values from reaching route handlers.

## Two-Stage Route Parameter Validation

SXO implements a defensive validation strategy that operates at different phases of the application lifecycle:

1. **Compile-time validation** – Enforces strict naming conventions for parameter placeholders during the build process.
2. **Runtime validation** – Validates actual URL values against `SLUG_REGEX` when processing incoming requests.

This dual-layer approach prevents developer errors from reaching production while protecting the application against path traversal and injection attacks.

## Compile-Time Name Validation

Before routes are assembled into the production manifest, SXO validates every dynamic segment placeholder using the `validateRoutePattern()` function defined in [`src/js/server/utils/route-match.js`](https://github.com/gc-victor/sxo/blob/main/src/js/server/utils/route-match.js).

### The validateRoutePattern Function

Called from `assembleRoutes()` during the build process, this function enforces three strict rules on parameter names:

- **Must start with a letter** – The first character must be `a-z` or `A-Z`.
- **Alphanumeric and underscores only** – Subsequent characters may include numbers (`0-9`) and underscores (`_`), but no hyphens, spaces, or special characters.
- **Unique within route** – Each placeholder name must appear only once within a single route pattern.

If any rule is violated, the build fails immediately with a descriptive error, preventing malformed route definitions from being deployed.

## Runtime Value Validation with SLUG_REGEX

When a request reaches the SXO server, the `routeMatch()` function in [`src/js/server/utils/route-match.js`](https://github.com/gc-victor/sxo/blob/main/src/js/server/utils/route-match.js) processes the URL against compiled route patterns. This is where `SLUG_REGEX` serves as the security gate for dynamic parameter values.

### How routeMatch Processes URLs

The matching algorithm follows this sequence:

1. **URL normalization** – Removes query strings and hash fragments from the incoming request path.
2. **Pattern matching** – Iterates through compiled routes to find a matching pattern.
3. **Value extraction** – For each dynamic segment (e.g., `[slug]`), extracts the corresponding value from the URL.
4. **Regex validation** – Tests the extracted value against `SLUG_REGEX`.

`SLUG_REGEX` is defined as a constant in [`src/js/server/utils/route-match.js`](https://github.com/gc-victor/sxo/blob/main/src/js/server/utils/route-match.js) and typically permits only "slug-safe" characters: alphanumeric characters, hyphens, and underscores.

When a value fails the regex test, `routeMatch()` returns an object containing `{ invalid: true }`. SXO's request-handling pipeline interprets this as a non-match, ultimately rendering a 404 response through the error handling logic in [`src/js/server/utils/error-pages.js`](https://github.com/gc-victor/sxo/blob/main/src/js/server/utils/error-pages.js).

## Practical Examples

### Valid Route Definition

The following example demonstrates a properly defined dynamic route that passes both validation stages:

```javascript
// pages/blog/[slug].js
export default ({ slug }) => `
  <html>
    <head><title>Blog – ${slug}</title></head>
    <body>
      <h1>Post: ${slug}</h1>
      <!-- Content rendered safely -->
    </body>
  </html>
`;

```

A request to `/blog/hello-world` succeeds because:
- The parameter name `slug` starts with a letter and contains only valid characters (compile-time check).
- The value `hello-world` matches `SLUG_REGEX` (runtime check).

### Invalid Slug Handling

When a URL contains characters that violate `SLUG_REGEX`, SXO rejects the request:

```bash

# Request with invalid characters

GET /blog/hello world!   # Contains space and exclamation mark

# SXO processing sequence:

# 1. Extracted value: "hello world!"

# 2. SLUG_REGEX test fails

# 3. routeMatch() returns { invalid: true }

# 4. Server responds with 404 Not Found

```

### Unit Testing Route Matching

The SXO test suite validates this behavior in [`src/js/server/utils/tests/route-match.test.js`](https://github.com/gc-victor/sxo/blob/main/src/js/server/utils/tests/route-match.test.js):

```javascript
import { routeMatch } from '../../src/js/server/utils/route-match.js';

test('rejects invalid slug values', () => {
  const result = routeMatch('/blog/invalid/slash/', [{ pattern: '/blog/[slug]' }]);
  expect(result).toEqual({ invalid: true });
});

```

This test confirms that values containing forward slashes (which violate slug safety rules) correctly trigger the invalid flag.

## Key Implementation Files

| Purpose | File Path |
|---------|-----------|
| **Route matching core (including `SLUG_REGEX`)** | [`src/js/server/utils/route-match.js`](https://github.com/gc-victor/sxo/blob/main/src/js/server/utils/route-match.js) |
| **Compile-time pattern validation** | [`src/js/server/utils/route-match.js`](https://github.com/gc-victor/sxo/blob/main/src/js/server/utils/route-match.js) (`validateRoutePattern` function) |
| **Unit tests for matching logic** | [`src/js/server/utils/tests/route-match.test.js`](https://github.com/gc-victor/sxo/blob/main/src/js/server/utils/tests/route-match.test.js) |
| **Route manifest assembly** | [`src/js/server/shared/routes-loader.js`](https://github.com/gc-victor/sxo/blob/main/src/js/server/shared/routes-loader.js) |
| **404 error handling** | [`src/js/server/utils/error-pages.js`](https://github.com/gc-victor/sxo/blob/main/src/js/server/utils/error-pages.js) |

## Summary

- **Two-stage validation** ensures route parameters are safe: `validateRoutePattern()` checks placeholder names at build time, while `SLUG_REGEX` validates values at runtime.
- **Compile-time rules** require parameter names to start with letters and contain only alphanumeric characters and underscores.
- **Runtime security** relies on `SLUG_REGEX` in [`src/js/server/utils/route-match.js`](https://github.com/gc-victor/sxo/blob/main/src/js/server/utils/route-match.js) to reject malformed slugs, returning `{ invalid: true }` to trigger 404 responses.
- **File locations** to examine: [`route-match.js`](https://github.com/gc-victor/sxo/blob/main/route-match.js) for core logic, [`route-match.test.js`](https://github.com/gc-victor/sxo/blob/main/route-match.test.js) for validation examples, and [`error-pages.js`](https://github.com/gc-victor/sxo/blob/main/error-pages.js) for fallback handling.

## Frequently Asked Questions

### What characters are allowed in SXO route parameter names?

Parameter names must start with a letter (`a-z` or `A-Z`) and can only contain letters, numbers, and underscores. Hyphens and special characters are prohibited in placeholder names like `[slug]` or `[post_id]`. This validation occurs during the build process via the `validateRoutePattern()` function in [`src/js/server/utils/route-match.js`](https://github.com/gc-victor/sxo/blob/main/src/js/server/utils/route-match.js).

### How does SXO handle invalid route parameter values?

When a URL contains a dynamic segment value that fails the `SLUG_REGEX` test, the `routeMatch()` function returns an object with `{ invalid: true }`. SXO's request pipeline interprets this result as a non-match and serves a 404 response through the error handling logic defined in [`src/js/server/utils/error-pages.js`](https://github.com/gc-victor/sxo/blob/main/src/js/server/utils/error-pages.js). This prevents malformed or potentially malicious values from reaching application handlers.

### Where is route parameter validation defined in the SXO codebase?

The core validation logic resides in [`src/js/server/utils/route-match.js`](https://github.com/gc-victor/sxo/blob/main/src/js/server/utils/route-match.js). This file contains the `validateRoutePattern()` function for compile-time name validation and the `SLUG_REGEX` constant used by `routeMatch()` for runtime value checking. Unit tests demonstrating validation behavior are located in [`src/js/server/utils/tests/route-match.test.js`](https://github.com/gc-victor/sxo/blob/main/src/js/server/utils/tests/route-match.test.js).

### Can I customize the SLUG_REGEX pattern in SXO?

The `SLUG_REGEX` is defined as a constant in [`src/js/server/utils/route-match.js`](https://github.com/gc-victor/sxo/blob/main/src/js/server/utils/route-match.js) and is used directly by the `routeMatch()` function. To customize the allowed character set for route parameters, you would need to modify the regex definition in that file and ensure the change aligns with the validation logic that returns `{ invalid: true }` for non-matching values. Be cautious when relaxing these restrictions, as the regex serves as a security boundary against path traversal attacks.