JavaScript-enabled Routing

Your routes, directly in JavaScript

Generate the URLs of your Symfony routes in JavaScript, exactly like path() and url() do in Twig.

composer require symfony/ux-router

What Router gives you

  • The same URLs

    Identical to what path() and url() return in Twig.

  • Only what you expose

    No route reaches JavaScript until you list it.

  • Typed parameters

    TypeScript checks route names and parameters.

  • Localized routes

    The current locale picks the right path.

  • Fresh in dev

    Change a route, the next request dumps it again.

Symfony Routes in JavaScript

Add Router to your app.

Generate your Symfony routes' URLs in JavaScript

config/packages/ux_router.yaml
ux_router:
    # Route name patterns exposed to JavaScript
    routes:
        - 'demo_*'
assets/router.js
import { createRouter } from '@symfony/ux-router';
import { routes } from '../var/routes/index.js';

/*
 * This file is part of the Symfony UX Router package.
 *
 * If folder "../var/routes" does not exist, or some routes are missing,
 * you must warmup your Symfony cache to refresh JavaScript routes.
 *
 * If you use TypeScript, you can rename this file to "router.ts" to take advantage of types checking.
 */

export const { path, url } = createRouter({ routes });
Symfony logo

UX Router

path('demo_blog_post', {
    slug: ,
    _query: { page:  },
})
Path with a query string
url('demo_blog_post', {
    slug: ,
})
Absolute URL
path('demo_about', {
    _locale: ,
})
Localized route
path('demo_blog_archive', {
    year: ,
})
Requirement check

Dumped at cache warmup

How the routes get there.

Nothing is fetched at runtime. A cache warmer writes the routes you expose to disk, and your JavaScript imports them like any other module.

Exposed on purpose

Name patterns, or the expose option of a route, decide what JavaScript can see.

ux_router:
    routes:
        - 'app_*'
        - '!app_admin_*'

Written to disk

The exposed routes end up in one generated module, with TypeScript types next to it.

var/routes/
├── index.js
└── index.d.ts

The same path() and url()

Requirements, defaults, hosts, schemes and the query string behave the way they do in PHP.

import { path, url } from './router.js';

path('app_blog_show', { slug: 'hello', _query: { page: 2 } });
// '/blog/hello?page=2'

url('app_blog_show', { slug: 'hello' });
// 'https://example.com/blog/hello'

Install Router.

$ composer require symfony/ux-router

More from Symfony UX.

Router is one package among many. They share the same Stimulus foundation and install the same way.

Image for the Stimulus UX package

Stimulus

Integration with Stimulus for HTML-powered controllers

Image for the Inspector UX package

Inspector New

Browser devtools for Stimulus controllers, Live Components and Turbo frames.

Image for the Toolkit UX package

Toolkit

Collection of components and templates that you can use to build your pages.

Browse every package

Keep Router at hand.

Documentation, the people behind it, and where to ask when something does not behave.