{"record":{"id":"3ee4412df2fd358e","repo":"withastro/astro","slug":"serveronlymodule","errorCode":"ServerOnlyModule","errorMessage":"The \"astro:content\" module is only available server-side.","messagePattern":"The \"astro:content\" module is only available server-side\\.","errorType":"error_code","errorClass":"AstroError","httpStatus":null,"severity":"error","filePath":"packages/astro/src/content/vite-plugin-content-virtual-mod.ts","lineNumber":373,"sourceCode":"\nasync function generateContentEntryFile({\n\tsettings,\n\tisClient,\n}: {\n\tsettings: AstroSettings;\n\tfs: typeof nodeFs;\n\tisClient: boolean;\n}) {\n\tconst contentPaths = getContentPaths(\n\t\tsettings.config,\n\t\tundefined,\n\t\tsettings.config.legacy?.collectionsBackwardsCompat,\n\t);\n\tconst relContentDir = rootRelativePath(settings.config.root, contentPaths.contentDir);\n\n\tlet virtualModContents: string;\n\tif (isClient) {\n\t\tthrow new AstroError({\n\t\t\t...AstroErrorData.ServerOnlyModule,\n\t\t\tmessage: AstroErrorData.ServerOnlyModule.message('astro:content'),\n\t\t});\n\t} else {\n\t\tvirtualModContents = nodeFs\n\t\t\t.readFileSync(contentPaths.virtualModTemplate, 'utf-8')\n\t\t\t.replace('@@CONTENT_DIR@@', relContentDir)\n\t\t\t.replace(\n\t\t\t\t'/* @@LIVE_CONTENT_CONFIG@@ */',\n\t\t\t\tcontentPaths.liveConfig.exists\n\t\t\t\t\t? // Dynamic import so it extracts the chunk and avoids a circular import\n\t\t\t\t\t\t`const liveCollections = (await import(${JSON.stringify(fileURLToPath(contentPaths.liveConfig.url))})).collections;`\n\t\t\t\t\t: 'const liveCollections = {};',\n\t\t\t);\n\t}\n\n\treturn virtualModContents;\n}","sourceCodeStart":355,"sourceCodeEnd":391,"githubUrl":"https://github.com/withastro/astro/blob/d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca/packages/astro/src/content/vite-plugin-content-virtual-mod.ts#L355-L391","documentation":"Thrown when the `astro:content` virtual module is imported in a client-side (browser) context. The virtual module plugin's `load` hook checks the `isClient` flag; since content collections rely on filesystem access and server-only APIs, importing `astro:content` in client JavaScript is not supported and the `ServerOnlyModule` error is thrown.","triggerScenarios":"The virtual module plugin's `load` hook is invoked with `isClient: true`. Code in a `.astro` component's client-side script, a `.js`/`.ts` file imported by client script, or a framework component (React/Vue/Svelte) running in the browser imports from `astro:content`.","commonSituations":"Trying to query content collections inside a React `useEffect` or Vue `onMounted`. Importing `getCollection` in a file that's bundled for the client. Accidentally adding `client:` directives to a component that imports `astro:content`. Moving server-side logic into a shared module that also gets imported client-side.","solutions":["Move all `astro:content` imports to server-only code (`.astro` frontmatter, endpoints, or `server` islands).","Pass collection data as props from the server to client components instead of importing `astro:content` in the client.","If using `client:` directives, ensure the component does not directly import `astro:content`.","Split shared utilities into a server-only module and a client-safe module."],"exampleFix":"// before — src/components/BlogList.jsx (client component)\nimport { getCollection } from 'astro:content';\nexport default function BlogList() {\n  const posts = await getCollection('blog'); // crashes in browser\n  return <ul>{posts.map(p => <li>{p.id}</li>)}</ul>;\n}\n\n// after — src/components/BlogList.jsx\nexport default function BlogList({ posts }) {\n  return <ul>{posts.map(p => <li>{p.id}</li>)}</ul>;\n}\n// parent .astro file fetches on server and passes as prop","handlingStrategy":"type-guard","validationCode":"// Ensure no client-side file imports astro:content\n// In vite.config or astro.config, you can add a build-time check:\nfunction assertNoClientContentImport(filePath: string, isClient: boolean) {\n  if (isClient) {\n    const content = readFileSync(filePath, 'utf-8');\n    if (content.includes(\"astro:content\")) {\n      throw new Error(`${filePath} imports astro:content but runs client-side`);\n    }\n  }\n}","typeGuard":"// Server-only context check\nfunction isServerSide(): boolean {\n  return typeof window === 'undefined';\n}","tryCatchPattern":null,"preventionTips":["Never import astro:content in files bundled for the client.","Fetch collection data in .astro frontmatter and pass as props.","Audit client: directives on components that may transitively import astro:content."],"tags":["content-collections","client-side","ssr","islands","virtual-module"],"backgroundTag":null,"analyzedSha":"d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca","analyzedAt":"2026-08-12T13:37:29.035Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}