diff --git a/.changeset/honest-ravens-double.md b/.changeset/honest-ravens-double.md
new file mode 100644
index 000000000000..2b917b223452
--- /dev/null
+++ b/.changeset/honest-ravens-double.md
@@ -0,0 +1,5 @@
+---
+"astro": patch
+---
+
+Fixes a prerendering issue for libraries in `node_modules` when a folder with an underscore is in the path.
diff --git a/packages/astro/src/core/util.ts b/packages/astro/src/core/util.ts
index a48a85d16b35..8c6e161b82f6 100644
--- a/packages/astro/src/core/util.ts
+++ b/packages/astro/src/core/util.ts
@@ -120,11 +120,23 @@ function isInjectedRoute(file: URL, settings: AstroSettings) {
}
function isPublicRoute(file: URL, config: AstroConfig): boolean {
- const pagesDir = resolvePages(config);
- const parts = file.toString().replace(pagesDir.toString(), '').split('/').slice(1);
+ const rootDir = config.root.toString();
+ const pagesDir = resolvePages(config).toString();
+ const fileDir = file.toString();
+
+ // Normalize the file directory path by removing the pagesDir prefix if it exists,
+ // otherwise remove the rootDir prefix.
+ const normalizedDir = fileDir.startsWith(pagesDir) ? fileDir.slice(pagesDir.length) : fileDir.slice(rootDir.length);
+
+ const parts = normalizedDir
+ .replace(pagesDir.toString(), '')
+ .split('/')
+ .slice(1);
+
for (const part of parts) {
if (part.startsWith('_')) return false;
}
+
return true;
}
diff --git a/packages/astro/test/fixtures/_underscore in folder name/astro.config.mjs b/packages/astro/test/fixtures/_underscore in folder name/astro.config.mjs
new file mode 100644
index 000000000000..206c3fa09a98
--- /dev/null
+++ b/packages/astro/test/fixtures/_underscore in folder name/astro.config.mjs
@@ -0,0 +1,8 @@
+import { defineConfig } from 'astro/config';
+import fakeIntegration from 'fake-astro-library';
+
+export default defineConfig({
+ integrations: [
+ fakeIntegration(),
+ ],
+});
diff --git a/packages/astro/test/fixtures/_underscore in folder name/node_modules/fake-astro-library/404.astro b/packages/astro/test/fixtures/_underscore in folder name/node_modules/fake-astro-library/404.astro
new file mode 100644
index 000000000000..64db1a009192
--- /dev/null
+++ b/packages/astro/test/fixtures/_underscore in folder name/node_modules/fake-astro-library/404.astro
@@ -0,0 +1,4 @@
+---
+export const prerender = true;
+---
+
Test 404
diff --git a/packages/astro/test/fixtures/_underscore in folder name/node_modules/fake-astro-library/index.ts b/packages/astro/test/fixtures/_underscore in folder name/node_modules/fake-astro-library/index.ts
new file mode 100644
index 000000000000..af16fd8743a0
--- /dev/null
+++ b/packages/astro/test/fixtures/_underscore in folder name/node_modules/fake-astro-library/index.ts
@@ -0,0 +1,16 @@
+export default function FakeIntegration() {
+ return {
+ name: 'fake-astro-library',
+ hooks: {
+ 'astro:config:setup': async ({
+ injectRoute,
+ }) => {
+ injectRoute({
+ pattern: '404',
+ entrypoint: 'fake-astro-library/404.astro',
+ prerender: true,
+ });
+ },
+ },
+ };
+}
diff --git a/packages/astro/test/fixtures/_underscore in folder name/node_modules/fake-astro-library/package.json b/packages/astro/test/fixtures/_underscore in folder name/node_modules/fake-astro-library/package.json
new file mode 100644
index 000000000000..d1471d7772f6
--- /dev/null
+++ b/packages/astro/test/fixtures/_underscore in folder name/node_modules/fake-astro-library/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "fake-astro-library",
+ "version": "0.0.0",
+ "private": true,
+ "exports": {
+ ".": "./index.ts",
+ "./404.astro": "./404.astro"
+ },
+ "dependencies": {
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/astro/test/fixtures/_underscore in folder name/src/pages/index.astro b/packages/astro/test/fixtures/_underscore in folder name/src/pages/index.astro
new file mode 100644
index 000000000000..5eafc90ea2b9
--- /dev/null
+++ b/packages/astro/test/fixtures/_underscore in folder name/src/pages/index.astro
@@ -0,0 +1,11 @@
+
+
+ Project with underscore in the folder name
+
+
+Testing
+
+
+
diff --git a/packages/astro/test/underscore-in-folder-name.test.js b/packages/astro/test/underscore-in-folder-name.test.js
new file mode 100644
index 000000000000..2074c9d49965
--- /dev/null
+++ b/packages/astro/test/underscore-in-folder-name.test.js
@@ -0,0 +1,25 @@
+import assert from 'node:assert/strict';
+import { before, describe, it } from 'node:test';
+import { loadFixture } from './test-utils.js';
+import testAdapter from './test-adapter.js';
+
+describe('Projects with a underscore in the folder name', () => {
+ let fixture;
+
+ before(async () => {
+ fixture = await loadFixture({
+ root: './fixtures/_underscore in folder name/',
+ output: 'hybrid',
+ adapter: testAdapter(),
+ });
+ await fixture.build();
+ });
+
+ it('includes page from node_modules/fake-astro-library', async () => {
+ const app = await fixture.loadTestAdapterApp();
+ /** @type {Set} */
+ const assets = app.manifest.assets;
+ assert.equal(assets.has('/index.html'), true);
+ assert.equal(assets.has('/404.html'), true);
+ });
+});