diff --git a/packages/create-sitecore-jss/src/templates/nextjs-personalize/src/pages/_middleware.ts b/packages/create-sitecore-jss/src/templates/nextjs-personalize/src/lib/middleware/plugins/personalize.ts similarity index 94% rename from packages/create-sitecore-jss/src/templates/nextjs-personalize/src/pages/_middleware.ts rename to packages/create-sitecore-jss/src/templates/nextjs-personalize/src/lib/middleware/plugins/personalize.ts index 1172a801cd..090b90e513 100644 --- a/packages/create-sitecore-jss/src/templates/nextjs-personalize/src/pages/_middleware.ts +++ b/packages/create-sitecore-jss/src/templates/nextjs-personalize/src/lib/middleware/plugins/personalize.ts @@ -1,9 +1,12 @@ // eslint-disable-next-line @typescript-eslint/no-unused-vars import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; +import { MiddlewarePlugin } from '..'; -// eslint-disable-next-line import/no-anonymous-default-export, @typescript-eslint/explicit-module-boundary-types -export default async function (req: NextRequest) { +export const personalizePlugin: MiddlewarePlugin = async function ( + req: NextRequest, + res: NextResponse +) { // no need to personalize for preview, layout data already prepared on XM Cloud for preview, // personalizeLayout function will not perform any transformation if pass not existing segment code: e.g. _default const isPreview = req.cookies['__prerender_bypass'] || req.cookies['__next_preview_data']; @@ -34,8 +37,7 @@ export default async function (req: NextRequest) { if (pathname) { // _segmentId_ is just special word to distinguish path with segment code // without local rewrite will not work, see bug: https://github.com/vercel-customer-feedback/edge-functions/issues/85 - const rewriteTo = - `/${req.nextUrl.locale || 'en'}/_segmentId_${segment}` + pathname; + const rewriteTo = `/${req.nextUrl.locale || 'en'}/_segmentId_${segment}` + pathname; const nextResponse = NextResponse.rewrite(rewriteTo); // set Boxever identification cookie @@ -50,8 +52,10 @@ export default async function (req: NextRequest) { } } - return; -} + return res; +}; + +personalizePlugin.order = 0; async function getSegmentForCurrentUser(req: NextRequest) { // ALL THOSE KEYS ALL PUBLIC, move to env variables in production implementation diff --git a/packages/create-sitecore-jss/src/templates/nextjs/scripts/generate-plugins.ts b/packages/create-sitecore-jss/src/templates/nextjs/scripts/generate-plugins.ts index b514ab6221..35dd141109 100644 --- a/packages/create-sitecore-jss/src/templates/nextjs/scripts/generate-plugins.ts +++ b/packages/create-sitecore-jss/src/templates/nextjs/scripts/generate-plugins.ts @@ -36,6 +36,11 @@ const pluginDefinitions = [ rootPath: 'src/lib/sitemap-fetcher/plugins', moduleType: ModuleType.ESM, }, + { + listPath: 'src/temp/middleware-plugins.ts', + rootPath: 'src/lib/middleware/plugins', + moduleType: ModuleType.ESM, + }, { listPath: 'src/temp/page-props-factory-plugins.ts', rootPath: 'src/lib/page-props-factory/plugins', diff --git a/packages/create-sitecore-jss/src/templates/nextjs/src/lib/middleware/index.ts b/packages/create-sitecore-jss/src/templates/nextjs/src/lib/middleware/index.ts new file mode 100644 index 0000000000..6b19505946 --- /dev/null +++ b/packages/create-sitecore-jss/src/templates/nextjs/src/lib/middleware/index.ts @@ -0,0 +1,22 @@ +import { NextResponse } from 'next/server'; +import type { NextFetchEvent, NextRequest } from 'next/server'; +import * as plugins from 'temp/middleware-plugins'; + +export interface MiddlewarePlugin { + /** + * Detect order when the plugin should be called, e.g. 0 - will be called first (can be a plugin which data is required for other plugins) + */ + order: number; + /** + * A middleware to be called, it's required to return @type {NextResponse} for other middlewares + */ + (req: NextRequest, res: NextResponse, ev: NextFetchEvent): Promise; +} + +export default async function middleware(req: NextRequest, ev: NextFetchEvent): Promise { + const response = NextResponse.next(); + + return (Object.values(plugins) as MiddlewarePlugin[]) + .sort((p1, p2) => p1.order - p2.order) + .reduce((p, plugin) => p.then((res) => plugin(req, res, ev)), Promise.resolve(response)); +} diff --git a/packages/create-sitecore-jss/src/templates/nextjs/src/pages/_middleware.ts b/packages/create-sitecore-jss/src/templates/nextjs/src/pages/_middleware.ts new file mode 100644 index 0000000000..1c2717558b --- /dev/null +++ b/packages/create-sitecore-jss/src/templates/nextjs/src/pages/_middleware.ts @@ -0,0 +1,7 @@ +import type { NextRequest } from 'next/server'; +import middleware from 'lib/middleware'; + +// eslint-disable-next-line +export default async function (req: NextRequest) { + return middleware(req); +}