From a83e362ee41174501a433c210a24696784d7368f Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Tue, 27 Aug 2024 16:35:44 -0400 Subject: [PATCH] Prevent usage of astro:content in the client (#11827) * Prevent usage of astro:content in the client * Fix build errors * Update .changeset/neat-dots-hear.md Co-authored-by: Emanuele Stoppa * Throw an AstroError * Just throw --------- Co-authored-by: Emanuele Stoppa --- .changeset/neat-dots-hear.md | 11 +++++++ .../vite-plugin-content-virtual-mod.ts | 30 +++++++++++-------- 2 files changed, 28 insertions(+), 13 deletions(-) create mode 100644 .changeset/neat-dots-hear.md diff --git a/.changeset/neat-dots-hear.md b/.changeset/neat-dots-hear.md new file mode 100644 index 0000000000..567e5c22e3 --- /dev/null +++ b/.changeset/neat-dots-hear.md @@ -0,0 +1,11 @@ +--- +'astro': major +--- + +Prevent usage of `astro:content` in the client + +Usage of `astro:content` in the client has always been discouraged because it leads to all of your content winding up in your client bundle, and can possibly leaks secrets. + +This formally makes doing so impossible, adding to the previous warning with errors. + +In the future Astro might add APIs for client-usage based on needs. diff --git a/packages/astro/src/content/vite-plugin-content-virtual-mod.ts b/packages/astro/src/content/vite-plugin-content-virtual-mod.ts index 832ca0b171..0ad253dd88 100644 --- a/packages/astro/src/content/vite-plugin-content-virtual-mod.ts +++ b/packages/astro/src/content/vite-plugin-content-virtual-mod.ts @@ -253,18 +253,22 @@ export async function generateContentEntryFile({ renderEntryGlobResult = getStringifiedCollectionFromLookup('render', relContentDir, lookupMap); } - let virtualModContents = - nodeFs - .readFileSync(contentPaths.virtualModTemplate, 'utf-8') - .replace('@@CONTENT_DIR@@', relContentDir) - .replace("'@@CONTENT_ENTRY_GLOB_PATH@@'", contentEntryGlobResult) - .replace("'@@DATA_ENTRY_GLOB_PATH@@'", dataEntryGlobResult) - .replace("'@@RENDER_ENTRY_GLOB_PATH@@'", renderEntryGlobResult) - .replace('/* @@LOOKUP_MAP_ASSIGNMENT@@ */', `lookupMap = ${JSON.stringify(lookupMap)};`) + - (isClient - ? ` -console.warn('astro:content is only supported running server-side. Using it in the browser will lead to bloated bundles and slow down page load. In the future it will not be supported.');` - : ''); + let virtualModContents: string; + if(isClient) { + throw new AstroError({ + ...AstroErrorData.ServerOnlyModule, + message: AstroErrorData.ServerOnlyModule.message('astro:content'), + }); + } else { + virtualModContents = + nodeFs + .readFileSync(contentPaths.virtualModTemplate, 'utf-8') + .replace('@@CONTENT_DIR@@', relContentDir) + .replace("'@@CONTENT_ENTRY_GLOB_PATH@@'", contentEntryGlobResult) + .replace("'@@DATA_ENTRY_GLOB_PATH@@'", dataEntryGlobResult) + .replace("'@@RENDER_ENTRY_GLOB_PATH@@'", renderEntryGlobResult) + .replace('/* @@LOOKUP_MAP_ASSIGNMENT@@ */', `lookupMap = ${JSON.stringify(lookupMap)};`); + } return virtualModContents; } @@ -360,7 +364,7 @@ export async function generateLookupMap({ const contentEntryType = contentEntryConfigByExt.get(extname(filePath)); if (!contentEntryType) throw UnexpectedLookupMapError; - const { id, slug: generatedSlug } = await getContentEntryIdAndSlug({ + const { id, slug: generatedSlug } = getContentEntryIdAndSlug({ entry: pathToFileURL(filePath), contentDir, collection,