Aram Mkrtchyan
Aram Mkrtchyan

Reputation: 2700

React Router v6 add custom param into createBrowserRouter

I need you help. I'm new in react router v6 so i need to add custom params in route object. But can't find any examples of it

 const AdminRoutes: FunctionComponent = () => {
      const router = createBrowserRouter([
        {
          path: '/',
          element: <Dashboard />,
          permission: ['edit'], //custom param
        },
      ]);
    
          return <RouterProvider router={router} />;
        };
        
  export default AdminRoutes;

   

Given Error -

Type '{ path: string; element: JSX.Element; permission: string[]; }' is not assignable to type 'RouteObject'.
  Object literal may only specify known properties, and 'permission' does not exist in type 'RouteObject'

Thanks for your help.

Upvotes: 1

Views: 5280

Answers (3)

Alexander
Alexander

Reputation: 21

import React from 'react';
import i18next from 'i18next';
import '../internationalization/i18next';
import {
  Navigate,
  IndexRouteObject,
  NonIndexRouteObject,
  createBrowserRouter,
} from 'react-router-dom';
import { LayoutAuth } from '../components';
import { SignIn } from '../containers';

type CustomRouteObjectParams = {
    category?: 'authorization' | 'administration';
    title?: string;
};

type CustomIndexRouteObject = IndexRouteObject & CustomRouteObjectParams;

type CustomNonIndexRouteObject = Omit<NonIndexRouteObject, 'children'> &
    CustomRouteObjectParams & {
        children?: (CustomIndexRouteObject | CustomNonIndexRouteObject)[];
    };

type CustomRouteConfig = CustomIndexRouteObject | CustomNonIndexRouteObject;

export const routes: CustomRouteConfig[] = [{
    path: '/auth',
    category: 'authorization',
    title: i18next.t('routes:auth'),
    element: <LayoutAuth />,
    children: [
        {
          index: true,
          element: <Navigate to="signin" />,
        },
        {
          path: '*',
          element: <Navigate to="signin" />,
        },
        {
          path: 'signin',
          title: i18next.t('routes:signin'),
          element: <SignIn />,
        },
      ],
}]

export const router = createBrowserRouter(routes);

export type TRoutes = typeof routes;

Upvotes: 2

Drew Reese
Drew Reese

Reputation: 203373

I'd suggest a more conventional RRD way of "injecting" behavior by recommending creating a route component that takes the additional parameter as a prop and handles the logic accordingly.

Example:

const PermissionLayout = ({ permission }) => {
  const hasPermission = ... permission logic ...

  return hasPermission ? <Outlet /> : <Navigate to="/" replace />;
};
const router = createBrowserRouter([
  {
    element: <PermissionLayout permission={['edit']} />
    children: [
      {
        path: "/",
        element: <Dashboard />,
      }
    ],
  },
  ...
]);

const AdminRoutes: FunctionComponent = () => {
  return <RouterProvider router={router} />;
};
        
export default AdminRoutes;

Upvotes: 3

CollinD
CollinD

Reputation: 7573

You should be able to declare this object as a different type that extends RouteObject if you want to use it for other things as well.

type CustomRouteConfig = RouteObject & { permission: string[] }

const routeConfig: CustomRouteConfig[] = [{
  path: '/',
  element: <Dashboard />,
  permission: ['edit'], //custom param
}];

// note: you don't want to instantiate this router
// inside a functioncomponent body.
// at least stick it in a useEffect, but most likely
// this should be static.
const router = createBrowserRouter(routeConfig);

export const AdminRoutes: FunctionComponent = () => 
  <RouterProvider router={router} />

Upvotes: 1

Related Questions