Skip to content

Callable RedirectsΒ #3042

@AgentEnder

Description

@AgentEnder

Description

When prerendering redirects, dynamic redirects do not work. Id like to have a callable version of +redirects, s.t. I can generate redirects for known routes in the case where im redirecting underneath a parameterized route. E.g.

I have a pages like:

Id like to be able to prerender a redirect at /entity/@[knownIds]/subentities, to redirect to page 1

Workaround

You can always write a custom vite plugin to author these files or a hosting provider specific config file yourself, for example I've written the following plugin to render a _redirects file for cloudflare pages:

/**
 * Vite Plugin for Cloudflare Pages _redirects file
 *
 * This plugin:
 * 1. Provides a place to configure redirects that are written to _redirects
 *
 * Usage in vite.config.ts:
 *   import { redirectsPlugin } from '../../scripts/vite/redirects-plugin';
 *   export default defineConfig({
 *     plugins: [redirectsPlugin({
 *       redirects: {
 *         '[source]': '[destination] [!code]?'
 *       }
 *     })],
 *   });
 */

import { existsSync, mkdirSync, writeFileSync } from 'fs';
import { join } from 'path';
import type { Plugin, ResolvedConfig } from 'vite';

type RedirectsConfig = Record<string, string>;

interface RedirectsPluginOptions {
  /**
   * Record<'[source]', '[destination] [!code]?'>
   */
  redirects: RedirectsConfig;
}

export function redirectsPlugin(options: RedirectsPluginOptions): Plugin {
  let config: ResolvedConfig;

  return {
    name: 'redirects-plugin',

    configResolved(resolvedConfig) {
      config = resolvedConfig;
    },

    writeBundle() {
      // Write _redirects to output directory
      const outDir = config.build.outDir;
      const resolvedOutDir = join(config.root, outDir);

      if (!existsSync(resolvedOutDir)) {
        mkdirSync(resolvedOutDir, { recursive: true });
      }

      const redirectsPath = join(resolvedOutDir, '_redirects');
      const lines = Object.entries(options.redirects).map((kv) => kv.join(' '));
      writeFileSync(redirectsPath, lines.join('\n'));
      console.log(`βœ“ Wrote ${lines.length} redirects to ${redirectsPath}`);
    },
  };
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions