this works really well to do lazy loading to make a performant SPA:
import dynamic from 'next/dynamic';
const DynamicComponents: Record<string, React.ComponentType<ComponentProps<any>>> = {
UserPushNotifUpdates: dynamic(() => import('@/components/dd/push-notif/push-notifs-component'), {
loading: () => <LoadingComponent />,
}),
MatchPublic: dynamic(() => import('@/components/dd/match/match-2'), {
loading: () => <LoadingComponent />,
}),
MatchPrivate: dynamic(() => import('@/components/dd/match/match'), {
loading: () => <LoadingComponent />,
}),
AdminHome: dynamic(() => import('@/components/dd/admin/home/admin-home'), {
loading: () => <LoadingComponent />,
}),
AdminDashboard: dynamic(() => import('@/components/dd/admin/dashboard/admin-dashboard'), {
loading: () => <LoadingComponent />,
}),
};
the problem is that for security anybody could load any component - I want to restrict access to components in the same way we do with pages.
To my best knowledge, with Next.js, these import calls bypass middleware.
is there a way to get the middleware to work so we can always intercept import calls to modules like this and check for access?
alright so this is pretty straightforward generally, sadly only some will understand it, the key part is to use update (backend) Next.js middleware to match on components/assets being loaded.
this line:
req.nextUrl?.pathname?.startsWith('_next/')
the above will match on the components that get loaded on front-end, and there you can put your backend logic
const privateRouteMatcher = createRouteMatcher([
'/u/(.*)',
'/api/p/(.*)',
]);
export default middleware(async (auth, req: NextRequest) => {
const res = NextResponse.next();
if (req.nextUrl?.pathname?.startsWith('_next/')) {
// HANDLE ACCESS CONTROL LOGIC HERE
res.headers.set('x-middleware-cache', 'no-cache');
return res;
}
// For non-private routes, return early with CORS headers
if (!privateRouteMatcher(req)) {
return res;
}
// route to rest of the app
return res;
});
export const config = {
matcher: [
'/(.*)',
],
};