Skip to content

Utility function to build a URL from route.id + params #9934

@darrylyeo

Description

@darrylyeo

Describe the problem

I'm setting up redirects for a route directory with multiple params (/blog/[slug], /blog/[slug]/[part], /blog/[slug]/[...rest], etc.) and want to build the new URL by replacing just one of them ([slug]).

I ended up doing this naive regex replacement on route.id which doesn't account for all the possible variations of route params in SvelteKit (matchers, optionals, templates etc.):

// routes/blog/+layout.ts

const redirects = {
    'old-slug': 'new-slug'
}

export const load: LayoutLoad = ({ route, params }) => {
    if (redirects[params.slug]) {
        const newParams = {
            ...params,
            slug: redirects[params.slug]
        }

        throw redirect(
            308,
            route.id.replace(/\[(?:\.\.\.)?([^\]]*)\]/g, (_, param) => newParams[param])
        )
    }
}

Describe the proposed solution

Expose SvelteKit's internal resolve_entry function as buildRouteURL in the $app/navigation module, which parses a given route id and builds a URL string with the given params.

Now implementing my LayoutLoad function is as easy as this:

export const load: LayoutLoad = ({ route, params }) => {
    if (redirects[params.slug]) {
        throw redirect(
            308,
            buildRouteURL(route.id, {
                ...params,
                slug: redirects[params.slug]
            })
        )
    }
}

Alternatives considered

Related: #8289 Let ParamMatcher functions return a string to redirect

Importance

nice to have

Metadata

Metadata

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions