From 31eb6c32e169435da169ae098245937df2f182e1 Mon Sep 17 00:00:00 2001 From: Pavel Milkevich Date: Mon, 4 Dec 2023 16:32:46 +0100 Subject: [PATCH] Move preview route and update usages of nextjs-adapter methods #773 --- next-env.d.ts | 1 - next.config.js | 2 +- package-lock.json | 44 --------------- package.json | 3 - src/apiold/preview.ts | 45 --------------- src/apiold/revalidate.ts | 52 ----------------- .../[locale]/[[...contentPath]]/layout.tsx | 10 ++-- src/app/[locale]/[[...contentPath]]/page.tsx | 21 ++----- src/app/api/preview/route.ts | 53 ++++++++++++++++++ src/app/api/revalidate/route.ts | 4 +- src/app/layout.tsx | 2 +- src/middleware.ts | 36 ++++-------- src/pages/404.module.css | 16 ------ src/pages/404.tsx | 12 ---- src/pages/[[...contentPath]].tsxold | 32 ----------- src/pages/_app.tsx | 56 ------------------- src/pages/_component.tsx | 46 --------------- src/pages/_document.tsx | 31 ---------- src/pages/_error.tsx | 26 --------- src/pages/_renderable.tsx | 46 --------------- 20 files changed, 79 insertions(+), 459 deletions(-) delete mode 100644 src/apiold/preview.ts delete mode 100644 src/apiold/revalidate.ts create mode 100644 src/app/api/preview/route.ts delete mode 100644 src/pages/404.module.css delete mode 100644 src/pages/404.tsx delete mode 100644 src/pages/[[...contentPath]].tsxold delete mode 100644 src/pages/_app.tsx delete mode 100644 src/pages/_component.tsx delete mode 100644 src/pages/_document.tsx delete mode 100644 src/pages/_error.tsx delete mode 100644 src/pages/_renderable.tsx diff --git a/next-env.d.ts b/next-env.d.ts index fd36f949..4f11a03d 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -1,6 +1,5 @@ /// /// -/// // NOTE: This file should not be edited // see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/next.config.js b/next.config.js index dbf38c6f..688a888e 100644 --- a/next.config.js +++ b/next.config.js @@ -26,7 +26,7 @@ async function getEnonicHeaders() { const config = { reactStrictMode: true, - trailingSlash: true, + trailingSlash: false, transpilePackages: ['@enonic/nextjs-adapter'], webpack: getEnonicWebpackConfig, headers: getEnonicHeaders, diff --git a/package-lock.json b/package-lock.json index d83f2235..19fa9162 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,17 +9,14 @@ "version": "2.0.0", "license": "Apache-2.0", "dependencies": { - "@formatjs/intl-localematcher": "^0.5.2", "cross-env": "^7.0.3", "html-react-parser": "^5.0.3", - "negotiator": "^0.6.3", "next": "^14.0.3", "react": "18.2.0", "react-dom": "18.2.0", "unescape": "^1.0.1" }, "devDependencies": { - "@types/negotiator": "^0.6.3", "@types/node": "^20.8.9", "@types/react": "18.2.33", "@types/react-dom": "^18.2.14", @@ -107,14 +104,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@formatjs/intl-localematcher": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.2.tgz", - "integrity": "sha512-txaaE2fiBMagLrR4jYhxzFO6wEdEG4TPMqrzBAcbr4HFUYzH/YC+lg6OIzKCHm8WgDdyQevxbAAV1OgcXctuGw==", - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.13", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", @@ -372,12 +361,6 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, - "node_modules/@types/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@types/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-JkXTOdKs5MF086b/pt8C3+yVp3iDUwG635L7oCH6HvJvvr6lSUU5oe/gLXnPEfYRROHjJIPgCV6cuAg8gGkntQ==", - "dev": true - }, "node_modules/@types/node": { "version": "20.8.10", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.10.tgz", @@ -2835,14 +2818,6 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/next": { "version": "14.0.3", "resolved": "https://registry.npmjs.org/next/-/next-14.0.3.tgz", @@ -4060,14 +4035,6 @@ "integrity": "sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==", "dev": true }, - "@formatjs/intl-localematcher": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.2.tgz", - "integrity": "sha512-txaaE2fiBMagLrR4jYhxzFO6wEdEG4TPMqrzBAcbr4HFUYzH/YC+lg6OIzKCHm8WgDdyQevxbAAV1OgcXctuGw==", - "requires": { - "tslib": "^2.4.0" - } - }, "@humanwhocodes/config-array": { "version": "0.11.13", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", @@ -4219,12 +4186,6 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, - "@types/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@types/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-JkXTOdKs5MF086b/pt8C3+yVp3iDUwG635L7oCH6HvJvvr6lSUU5oe/gLXnPEfYRROHjJIPgCV6cuAg8gGkntQ==", - "dev": true - }, "@types/node": { "version": "20.8.10", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.10.tgz", @@ -6015,11 +5976,6 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" - }, "next": { "version": "14.0.3", "resolved": "https://registry.npmjs.org/next/-/next-14.0.3.tgz", diff --git a/package.json b/package.json index 5313fc1c..c7177271 100644 --- a/package.json +++ b/package.json @@ -11,17 +11,14 @@ "lint": "next lint" }, "dependencies": { - "@formatjs/intl-localematcher": "^0.5.2", "cross-env": "^7.0.3", "html-react-parser": "^5.0.3", - "negotiator": "^0.6.3", "next": "^14.0.3", "react": "18.2.0", "react-dom": "18.2.0", "unescape": "^1.0.1" }, "devDependencies": { - "@types/negotiator": "^0.6.3", "@types/node": "^20.8.9", "@types/react": "18.2.33", "@types/react-dom": "^18.2.14", diff --git a/src/apiold/preview.ts b/src/apiold/preview.ts deleted file mode 100644 index f6e08a6d..00000000 --- a/src/apiold/preview.ts +++ /dev/null @@ -1,45 +0,0 @@ -import {JSESSIONID_HEADER, PROJECT_ID_HEADER, RENDER_MODE_HEADER, XP_BASE_URL_HEADER} from '@enonic/nextjs-adapter'; -import {ParsedUrlQuery} from 'querystring'; -import {NextApiRequest, NextApiResponse} from 'next'; - -export default async function handler(req: NextApiRequest, res: NextApiResponse) { - const {token, path} = req.query; - if (token !== process.env.ENONIC_API_TOKEN) { - // XP hijacks 401 to show login page, so send 407 instead - return res.status(407).json({message: 'Invalid token'}); - } - - // If the slug doesn't exist prevent preview mode from being enabled - if (path === undefined) { - return res.status(400).json({message: 'Invalid path'}); - } - const reqParams = extractParams(req.query, ['token', 'path']); - - console.info(`Previewing [${path}]...`); - // Enable Preview Mode by setting the cookies - // getStaticProps will be called in response to this request - // Do not use previewData because we cache preview token - // and data in lib-nextjs-proxy across requests - res.setPreviewData({ - contentPath: path, - params: reqParams, - headers: { - [RENDER_MODE_HEADER]: req.headers[RENDER_MODE_HEADER], - [PROJECT_ID_HEADER]: req.headers[PROJECT_ID_HEADER], - [XP_BASE_URL_HEADER]: req.headers[XP_BASE_URL_HEADER], - [JSESSIONID_HEADER]: req.headers[JSESSIONID_HEADER] - } - }); - - res.redirect(path as string); -} - -function extractParams(query: ParsedUrlQuery, omit: string[]) { - return Object.entries(query).reduce((prev: Record, curr: any) => { - const [key, val] = curr; - if (omit.indexOf(key) < 0) { - prev[key] = val; - } - return prev; - }, {}); -} diff --git a/src/apiold/revalidate.ts b/src/apiold/revalidate.ts deleted file mode 100644 index 8be6c6f6..00000000 --- a/src/apiold/revalidate.ts +++ /dev/null @@ -1,52 +0,0 @@ -import {ContentPathItem, fetchContentPathsForLocale, getLocaleProjectConfigById, PROJECT_ID_HEADER} from '@enonic/nextjs-adapter'; -import {NextApiRequest, NextApiResponse} from 'next'; - -interface ResponseData { - message: string -} - -export default async function handler(req: NextApiRequest, res: NextApiResponse) { - const {token, path} = req.query; - // Check for secret to confirm this is a valid request - if (token !== process.env.ENONIC_API_TOKEN) { - // XP hijacks 401 to show login page, so send 407 instead - return res.status(407).json({message: 'Invalid token'}); - } - - try { - // Return 200 immediately and do revalidate in background - res.status(200).json({message: 'Revalidation started'}); - if (!path) { - console.info('Started revalidating everything...'); - const projectId = req.headers[PROJECT_ID_HEADER] as string | undefined; - const config = getLocaleProjectConfigById(projectId); - const paths = await fetchContentPathsForLocale('\${site}/', config); - const promises = paths.map((item: ContentPathItem) => { - const cp = item.params.contentPath; - if (cp[0] === "") { - cp[0] = config.locale; - } else { - cp.unshift(config.locale); - } - return revalidatePath(res, cp); - }); - await Promise.all(promises); - console.info(`Done revalidating everything`); - } else { - await revalidatePath(res, path); - console.info(`Revalidated [${path}]`); - } - } catch (err) { - console.error(`Revalidation [${path ?? 'everything'}] error: ` + err); - } -} - -async function revalidatePath(res: any, path: string[] | string) { - let normalPath; - if (typeof path === 'string') { - normalPath = path.charAt(0) !== '/' ? '/' + path : path; - } else { - normalPath = '/' + path.join('/'); - } - return res.revalidate(normalPath); -} diff --git a/src/app/[locale]/[[...contentPath]]/layout.tsx b/src/app/[locale]/[[...contentPath]]/layout.tsx index 65a67bba..7ee7444c 100644 --- a/src/app/[locale]/[[...contentPath]]/layout.tsx +++ b/src/app/[locale]/[[...contentPath]]/layout.tsx @@ -10,9 +10,9 @@ export type LayoutProps = { children: ReactNode } -export default async function ContentLayout(props: LayoutProps) { +export default async function ContentLayout({params, children}: LayoutProps) { - const {meta, common} = await fetchContent(props.params.contentPath) + const {meta, common} = await fetchContent(params); return (<>
@@ -21,16 +21,16 @@ export default async function ContentLayout(props: LayoutProps) { maxWidth: 960, padding: `0 1rem`, }}> - {props.children} + {children}