/** * @file no-next-cookies-in-pages.js * * Forbid direct cookie access in Next.js App Router pages. * * Rationale: * - Pages should stay focused on orchestration/rendering. * - Cookie parsing/auth/session concerns belong in middleware/layout boundaries or gateways. */ module.exports = { meta: { type: 'problem', docs: { description: 'Forbid using next/headers cookies() in app/**/page.* files', category: 'Architecture', recommended: true, }, schema: [], messages: { noCookiesInPages: 'Do not use cookies() in App Router pages. Move cookie/session handling to a layout boundary or middleware (or a dedicated gateway).', }, }, create(context) { const filename = context.getFilename(); const isPageFile = /\/app\/.*\/page\.(ts|tsx)$/.test(filename); if (!isPageFile) return {}; return { ImportDeclaration(node) { if (node.source && node.source.value === 'next/headers') { for (const spec of node.specifiers || []) { if (spec.type === 'ImportSpecifier' && spec.imported && spec.imported.name === 'cookies') { context.report({ node: spec, messageId: 'noCookiesInPages' }); } } } }, CallExpression(node) { if (node.callee && node.callee.type === 'Identifier' && node.callee.name === 'cookies') { context.report({ node, messageId: 'noCookiesInPages' }); } }, ImportExpression(node) { // Also catch: await import('next/headers') in a page. if (node.source && node.source.type === 'Literal' && node.source.value === 'next/headers') { context.report({ node, messageId: 'noCookiesInPages' }); } }, }; }, };