From d7086fbf439720a1421bdf60416317192c77425c Mon Sep 17 00:00:00 2001 From: Shah Shalin Date: Thu, 30 Jan 2025 14:23:42 +0530 Subject: [PATCH 01/18] fix: added a proxy API route which will make request to our WordPress server for the required module. Replaced the WordPress url from our module handle with our API route. --- examples/nextjs/starter/package-lock.json | 106 ++++++++++++++++++ .../api/proxy/js/module/[...path]/route.ts | 57 ++++++++++ .../next/src/components/script-module.tsx | 8 +- .../template-renderer/template-scripts.tsx | 2 +- 4 files changed, 169 insertions(+), 4 deletions(-) create mode 100644 examples/nextjs/starter/src/app/api/proxy/js/module/[...path]/route.ts diff --git a/examples/nextjs/starter/package-lock.json b/examples/nextjs/starter/package-lock.json index be658380..b3e6f780 100644 --- a/examples/nextjs/starter/package-lock.json +++ b/examples/nextjs/starter/package-lock.json @@ -123,6 +123,7 @@ } }, "../../../packages/next": { + "name": "@snapwp/next", "version": "0.0.1", "dependencies": { "html-react-parser": "^5.1.12", @@ -3031,6 +3032,111 @@ "node": ">= 10" } }, + "node_modules/@next/swc-darwin-x64": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.1.6.tgz", + "integrity": "sha512-x1jGpbHbZoZ69nRuogGL2MYPLqohlhnT9OCU6E6QFewwup+z+M6r8oU47BTeJcWsF2sdBahp5cKiAcDbwwK/lg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.1.6.tgz", + "integrity": "sha512-jar9sFw0XewXsBzPf9runGzoivajeWJUc/JkfbLTC4it9EhU8v7tCRLH7l5Y1ReTMN6zKJO0kKAGqDk8YSO2bg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.1.6.tgz", + "integrity": "sha512-+n3u//bfsrIaZch4cgOJ3tXCTbSxz0s6brJtU3SzLOvkJlPQMJ+eHVRi6qM2kKKKLuMY+tcau8XD9CJ1OjeSQQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.1.6.tgz", + "integrity": "sha512-SpuDEXixM3PycniL4iVCLyUyvcl6Lt0mtv3am08sucskpG0tYkW1KlRhTgj4LI5ehyxriVVcfdoxuuP8csi3kQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.1.6.tgz", + "integrity": "sha512-L4druWmdFSZIIRhF+G60API5sFB7suTbDRhYWSjiw0RbE+15igQvE2g2+S973pMGvwN3guw7cJUjA/TmbPWTHQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.1.6.tgz", + "integrity": "sha512-s8w6EeqNmi6gdvM19tqKKWbCyOBvXFbndkGHl+c9YrzsLARRdCHsD9S1fMj8gsXm9v8vhC8s3N8rjuC/XrtkEg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.1.6.tgz", + "integrity": "sha512-6xomMuu54FAFxttYr5PJbEfu96godcxBTRk1OhAvJq0/EnmFU/Ybiax30Snis4vdWZ9LGpf7Roy5fSs7v/5ROQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", diff --git a/examples/nextjs/starter/src/app/api/proxy/js/module/[...path]/route.ts b/examples/nextjs/starter/src/app/api/proxy/js/module/[...path]/route.ts new file mode 100644 index 00000000..44d8b22a --- /dev/null +++ b/examples/nextjs/starter/src/app/api/proxy/js/module/[...path]/route.ts @@ -0,0 +1,57 @@ +import { NextResponse } from 'next/server'; +import type { NextRequest } from 'next/server'; +import { getConfig } from '@snapwp/core/config'; + +/** + * Proxies a request to WordPress API. + * + * @param request The incoming request. + * @param root0 The parameters for the request. + * @param root0.params The parameters for the request. + * @param root0.params.path The path to the external API. + * + * @return The response from the external API. + */ +export async function GET( + request: NextRequest, + { params }: { params: { path: string[] } } +) { + const { path } = params; + + const { homeUrl } = getConfig(); + // Construct the target URL + const targetUrl = new URL( path.join( '/' ), homeUrl ).toString(); + + try { + // Forward the request to the external API + const response = await fetch( targetUrl, { + headers: { + 'Content-Type': 'application/javascript', // Ensure the correct MIME type + }, + } ); + + // Check if the response is OK + if ( ! response.ok ) { + throw new Error( + `Error from external API: ${ response.statusText }` + ); + } + + // Get the response data + const data = await response.text(); + + // Return the response with the correct Content-Type header + return new NextResponse( data, { + headers: { + 'Content-Type': 'application/javascript', + }, + } ); + } catch ( error ) { + // eslint-disable-next-line no-console + console.error( 'Proxy error:', error ); + return NextResponse.json( + { error: 'Internal Server Error' }, + { status: 500 } + ); + } +} diff --git a/packages/next/src/components/script-module.tsx b/packages/next/src/components/script-module.tsx index 12a1bd03..6727c6b7 100644 --- a/packages/next/src/components/script-module.tsx +++ b/packages/next/src/components/script-module.tsx @@ -9,6 +9,7 @@ */ import React, { type PropsWithoutRef } from 'react'; import Script from 'next/script'; +import { getConfig } from '@snapwp/core/config'; interface ScriptModuleInterface { handle?: string | null; @@ -43,6 +44,7 @@ export default function ScriptModule( { extraData, ...props }: PropsWithoutRef< ScriptModuleInterface > ) { + const { homeUrl } = getConfig(); // Generate dependency scripts const DependencyScripts = dependencies?.map( ( dep, index ) => { if ( ! dep?.connectedScriptModule ) { @@ -58,7 +60,7 @@ export default function ScriptModule( { rel="preload" as="script" key={ depHandle || `${ handle }-dep-${ index }` } - href={ depSrc } + href={ depSrc.replace( homeUrl, '/api/proxy/js/module' ) } id={ `${ depHandle }-js-modulepreload` } /> ); @@ -69,7 +71,7 @@ export default function ScriptModule( { key={ depHandle || `${ handle }-dep-${ index }` } id={ depHandle || undefined } type="module" - src={ depSrc } + src={ depSrc.replace( homeUrl, '/api/proxy/js/module' ) } /* * Use lazyOnload strategy for dependencies to ensure they are loaded asynchronously. * This strategy is recommended for non-blocking scripts and they prevent preload warnings. @@ -96,7 +98,7 @@ export default function ScriptModule( { const MainScript = src && (