├── .gitignore ├── README.md ├── app ├── blog │ └── [slug] │ │ └── page.tsx └── layout.tsx ├── docs └── hello-world.mdx ├── mdx-components.tsx ├── next.config.ts ├── package.json ├── pnpm-lock.yaml └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Next.js App Router + Dynamic MDX 2 | 3 | This is an example of loading MDX files from a folder outside of `app/`. 4 | 5 | For example, I have `app/blog/[slug]/page.tsx`, which uses a dynamic import: 6 | 7 | ```tsx 8 | export default async function Page({ 9 | params, 10 | }: { 11 | params: Promise<{ slug: string }>; 12 | }) { 13 | const slug = (await params).slug; 14 | const { default: Post } = await import(`docs/${slug}.mdx`); 15 | 16 | return ; 17 | } 18 | 19 | export function generateStaticParams() { 20 | return [{ slug: 'hello-world' }]; 21 | } 22 | 23 | export const dynamicParams = false; 24 | ``` 25 | 26 | This reads an MDX file from the top-level `docs/` folder: 27 | 28 | ```md 29 | # Hello 30 | 31 | world 32 | ``` 33 | -------------------------------------------------------------------------------- /app/blog/[slug]/page.tsx: -------------------------------------------------------------------------------- 1 | export default async function Page({ 2 | params, 3 | }: { 4 | params: Promise<{ slug: string }>; 5 | }) { 6 | const slug = (await params).slug; 7 | const { default: Post } = await import(`docs/${slug}.mdx`); 8 | 9 | return ; 10 | } 11 | 12 | export function generateStaticParams() { 13 | return [{ slug: 'hello-world' }]; 14 | } 15 | 16 | export const dynamicParams = false; 17 | -------------------------------------------------------------------------------- /app/layout.tsx: -------------------------------------------------------------------------------- 1 | export default function RootLayout({ 2 | children, 3 | }: { 4 | children: React.ReactNode; 5 | }) { 6 | return ( 7 | 8 | {children} 9 | 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /docs/hello-world.mdx: -------------------------------------------------------------------------------- 1 | # Hello 2 | 3 | world 4 | -------------------------------------------------------------------------------- /mdx-components.tsx: -------------------------------------------------------------------------------- 1 | export function useMDXComponents() { 2 | return { 3 | h1: ({ children }: { children: React.ReactNode }) => ( 4 |

{children}

5 | ), 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /next.config.ts: -------------------------------------------------------------------------------- 1 | import type { NextConfig } from 'next'; 2 | import createMDX from '@next/mdx'; 3 | 4 | const nextConfig = { 5 | pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'mdx'], 6 | experimental: { 7 | mdxRs: true, 8 | }, 9 | } satisfies NextConfig; 10 | 11 | const withMDX = createMDX({}); 12 | 13 | export default withMDX(nextConfig); 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "next dev --turbopack", 5 | "build": "next build", 6 | "start": "next start" 7 | }, 8 | "dependencies": { 9 | "@next/mdx": "latest", 10 | "@types/node": "18.11.18", 11 | "@types/react": "18.2.8", 12 | "@types/react-dom": "18.0.10", 13 | "next": "latest", 14 | "react": "18.2.0", 15 | "react-dom": "18.2.0", 16 | "typescript": "4.9.5" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | '@next/mdx': 12 | specifier: latest 13 | version: 15.0.3 14 | '@types/node': 15 | specifier: 18.11.18 16 | version: 18.11.18 17 | '@types/react': 18 | specifier: 18.2.8 19 | version: 18.2.8 20 | '@types/react-dom': 21 | specifier: 18.0.10 22 | version: 18.0.10 23 | next: 24 | specifier: latest 25 | version: 15.0.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) 26 | react: 27 | specifier: 18.2.0 28 | version: 18.2.0 29 | react-dom: 30 | specifier: 18.2.0 31 | version: 18.2.0(react@18.2.0) 32 | typescript: 33 | specifier: 4.9.5 34 | version: 4.9.5 35 | 36 | packages: 37 | 38 | '@emnapi/runtime@1.3.1': 39 | resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==} 40 | 41 | '@img/sharp-darwin-arm64@0.33.5': 42 | resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} 43 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 44 | cpu: [arm64] 45 | os: [darwin] 46 | 47 | '@img/sharp-darwin-x64@0.33.5': 48 | resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} 49 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 50 | cpu: [x64] 51 | os: [darwin] 52 | 53 | '@img/sharp-libvips-darwin-arm64@1.0.4': 54 | resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} 55 | cpu: [arm64] 56 | os: [darwin] 57 | 58 | '@img/sharp-libvips-darwin-x64@1.0.4': 59 | resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} 60 | cpu: [x64] 61 | os: [darwin] 62 | 63 | '@img/sharp-libvips-linux-arm64@1.0.4': 64 | resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} 65 | cpu: [arm64] 66 | os: [linux] 67 | 68 | '@img/sharp-libvips-linux-arm@1.0.5': 69 | resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} 70 | cpu: [arm] 71 | os: [linux] 72 | 73 | '@img/sharp-libvips-linux-s390x@1.0.4': 74 | resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} 75 | cpu: [s390x] 76 | os: [linux] 77 | 78 | '@img/sharp-libvips-linux-x64@1.0.4': 79 | resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} 80 | cpu: [x64] 81 | os: [linux] 82 | 83 | '@img/sharp-libvips-linuxmusl-arm64@1.0.4': 84 | resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} 85 | cpu: [arm64] 86 | os: [linux] 87 | 88 | '@img/sharp-libvips-linuxmusl-x64@1.0.4': 89 | resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} 90 | cpu: [x64] 91 | os: [linux] 92 | 93 | '@img/sharp-linux-arm64@0.33.5': 94 | resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} 95 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 96 | cpu: [arm64] 97 | os: [linux] 98 | 99 | '@img/sharp-linux-arm@0.33.5': 100 | resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} 101 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 102 | cpu: [arm] 103 | os: [linux] 104 | 105 | '@img/sharp-linux-s390x@0.33.5': 106 | resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} 107 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 108 | cpu: [s390x] 109 | os: [linux] 110 | 111 | '@img/sharp-linux-x64@0.33.5': 112 | resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} 113 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 114 | cpu: [x64] 115 | os: [linux] 116 | 117 | '@img/sharp-linuxmusl-arm64@0.33.5': 118 | resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} 119 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 120 | cpu: [arm64] 121 | os: [linux] 122 | 123 | '@img/sharp-linuxmusl-x64@0.33.5': 124 | resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} 125 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 126 | cpu: [x64] 127 | os: [linux] 128 | 129 | '@img/sharp-wasm32@0.33.5': 130 | resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} 131 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 132 | cpu: [wasm32] 133 | 134 | '@img/sharp-win32-ia32@0.33.5': 135 | resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} 136 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 137 | cpu: [ia32] 138 | os: [win32] 139 | 140 | '@img/sharp-win32-x64@0.33.5': 141 | resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} 142 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 143 | cpu: [x64] 144 | os: [win32] 145 | 146 | '@next/env@15.0.3': 147 | resolution: {integrity: sha512-t9Xy32pjNOvVn2AS+Utt6VmyrshbpfUMhIjFO60gI58deSo/KgLOp31XZ4O+kY/Is8WAGYwA5gR7kOb1eORDBA==} 148 | 149 | '@next/mdx@15.0.3': 150 | resolution: {integrity: sha512-EwCJKDeJqfbHbsS7rIdWpKDOZsOPsif9AX4PaIhy5ghSMsZvi+/vIZVc07pZT7BdwCIoL9XM1KZMd/vzxCxF5A==} 151 | peerDependencies: 152 | '@mdx-js/loader': '>=0.15.0' 153 | '@mdx-js/react': '>=0.15.0' 154 | peerDependenciesMeta: 155 | '@mdx-js/loader': 156 | optional: true 157 | '@mdx-js/react': 158 | optional: true 159 | 160 | '@next/swc-darwin-arm64@15.0.3': 161 | resolution: {integrity: sha512-s3Q/NOorCsLYdCKvQlWU+a+GeAd3C8Rb3L1YnetsgwXzhc3UTWrtQpB/3eCjFOdGUj5QmXfRak12uocd1ZiiQw==} 162 | engines: {node: '>= 10'} 163 | cpu: [arm64] 164 | os: [darwin] 165 | 166 | '@next/swc-darwin-x64@15.0.3': 167 | resolution: {integrity: sha512-Zxl/TwyXVZPCFSf0u2BNj5sE0F2uR6iSKxWpq4Wlk/Sv9Ob6YCKByQTkV2y6BCic+fkabp9190hyrDdPA/dNrw==} 168 | engines: {node: '>= 10'} 169 | cpu: [x64] 170 | os: [darwin] 171 | 172 | '@next/swc-linux-arm64-gnu@15.0.3': 173 | resolution: {integrity: sha512-T5+gg2EwpsY3OoaLxUIofmMb7ohAUlcNZW0fPQ6YAutaWJaxt1Z1h+8zdl4FRIOr5ABAAhXtBcpkZNwUcKI2fw==} 174 | engines: {node: '>= 10'} 175 | cpu: [arm64] 176 | os: [linux] 177 | 178 | '@next/swc-linux-arm64-musl@15.0.3': 179 | resolution: {integrity: sha512-WkAk6R60mwDjH4lG/JBpb2xHl2/0Vj0ZRu1TIzWuOYfQ9tt9NFsIinI1Epma77JVgy81F32X/AeD+B2cBu/YQA==} 180 | engines: {node: '>= 10'} 181 | cpu: [arm64] 182 | os: [linux] 183 | 184 | '@next/swc-linux-x64-gnu@15.0.3': 185 | resolution: {integrity: sha512-gWL/Cta1aPVqIGgDb6nxkqy06DkwJ9gAnKORdHWX1QBbSZZB+biFYPFti8aKIQL7otCE1pjyPaXpFzGeG2OS2w==} 186 | engines: {node: '>= 10'} 187 | cpu: [x64] 188 | os: [linux] 189 | 190 | '@next/swc-linux-x64-musl@15.0.3': 191 | resolution: {integrity: sha512-QQEMwFd8r7C0GxQS62Zcdy6GKx999I/rTO2ubdXEe+MlZk9ZiinsrjwoiBL5/57tfyjikgh6GOU2WRQVUej3UA==} 192 | engines: {node: '>= 10'} 193 | cpu: [x64] 194 | os: [linux] 195 | 196 | '@next/swc-win32-arm64-msvc@15.0.3': 197 | resolution: {integrity: sha512-9TEp47AAd/ms9fPNgtgnT7F3M1Hf7koIYYWCMQ9neOwjbVWJsHZxrFbI3iEDJ8rf1TDGpmHbKxXf2IFpAvheIQ==} 198 | engines: {node: '>= 10'} 199 | cpu: [arm64] 200 | os: [win32] 201 | 202 | '@next/swc-win32-x64-msvc@15.0.3': 203 | resolution: {integrity: sha512-VNAz+HN4OGgvZs6MOoVfnn41kBzT+M+tB+OK4cww6DNyWS6wKaDpaAm/qLeOUbnMh0oVx1+mg0uoYARF69dJyA==} 204 | engines: {node: '>= 10'} 205 | cpu: [x64] 206 | os: [win32] 207 | 208 | '@swc/counter@0.1.3': 209 | resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} 210 | 211 | '@swc/helpers@0.5.13': 212 | resolution: {integrity: sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==} 213 | 214 | '@types/node@18.11.18': 215 | resolution: {integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==} 216 | 217 | '@types/prop-types@15.7.13': 218 | resolution: {integrity: sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==} 219 | 220 | '@types/react-dom@18.0.10': 221 | resolution: {integrity: sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==} 222 | 223 | '@types/react@18.2.8': 224 | resolution: {integrity: sha512-lTyWUNrd8ntVkqycEEplasWy2OxNlShj3zqS0LuB1ENUGis5HodmhM7DtCoUGbxj3VW/WsGA0DUhpG6XrM7gPA==} 225 | 226 | '@types/scheduler@0.23.0': 227 | resolution: {integrity: sha512-YIoDCTH3Af6XM5VuwGG/QL/CJqga1Zm3NkU3HZ4ZHK2fRMPYP1VczsTUqtsf43PH/iJNVlPHAo2oWX7BSdB2Hw==} 228 | 229 | busboy@1.6.0: 230 | resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} 231 | engines: {node: '>=10.16.0'} 232 | 233 | caniuse-lite@1.0.30001686: 234 | resolution: {integrity: sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA==} 235 | 236 | client-only@0.0.1: 237 | resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} 238 | 239 | color-convert@2.0.1: 240 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 241 | engines: {node: '>=7.0.0'} 242 | 243 | color-name@1.1.4: 244 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 245 | 246 | color-string@1.9.1: 247 | resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} 248 | 249 | color@4.2.3: 250 | resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} 251 | engines: {node: '>=12.5.0'} 252 | 253 | csstype@3.1.3: 254 | resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} 255 | 256 | detect-libc@2.0.3: 257 | resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} 258 | engines: {node: '>=8'} 259 | 260 | is-arrayish@0.3.2: 261 | resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} 262 | 263 | js-tokens@4.0.0: 264 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 265 | 266 | loose-envify@1.4.0: 267 | resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} 268 | hasBin: true 269 | 270 | nanoid@3.3.8: 271 | resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} 272 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 273 | hasBin: true 274 | 275 | next@15.0.3: 276 | resolution: {integrity: sha512-ontCbCRKJUIoivAdGB34yCaOcPgYXr9AAkV/IwqFfWWTXEPUgLYkSkqBhIk9KK7gGmgjc64B+RdoeIDM13Irnw==} 277 | engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} 278 | hasBin: true 279 | peerDependencies: 280 | '@opentelemetry/api': ^1.1.0 281 | '@playwright/test': ^1.41.2 282 | babel-plugin-react-compiler: '*' 283 | react: ^18.2.0 || 19.0.0-rc-66855b96-20241106 284 | react-dom: ^18.2.0 || 19.0.0-rc-66855b96-20241106 285 | sass: ^1.3.0 286 | peerDependenciesMeta: 287 | '@opentelemetry/api': 288 | optional: true 289 | '@playwright/test': 290 | optional: true 291 | babel-plugin-react-compiler: 292 | optional: true 293 | sass: 294 | optional: true 295 | 296 | picocolors@1.1.1: 297 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 298 | 299 | postcss@8.4.31: 300 | resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} 301 | engines: {node: ^10 || ^12 || >=14} 302 | 303 | react-dom@18.2.0: 304 | resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} 305 | peerDependencies: 306 | react: ^18.2.0 307 | 308 | react@18.2.0: 309 | resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} 310 | engines: {node: '>=0.10.0'} 311 | 312 | scheduler@0.23.2: 313 | resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} 314 | 315 | semver@7.6.3: 316 | resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} 317 | engines: {node: '>=10'} 318 | hasBin: true 319 | 320 | sharp@0.33.5: 321 | resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} 322 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 323 | 324 | simple-swizzle@0.2.2: 325 | resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} 326 | 327 | source-map-js@1.2.1: 328 | resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} 329 | engines: {node: '>=0.10.0'} 330 | 331 | source-map@0.7.4: 332 | resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} 333 | engines: {node: '>= 8'} 334 | 335 | streamsearch@1.1.0: 336 | resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} 337 | engines: {node: '>=10.0.0'} 338 | 339 | styled-jsx@5.1.6: 340 | resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} 341 | engines: {node: '>= 12.0.0'} 342 | peerDependencies: 343 | '@babel/core': '*' 344 | babel-plugin-macros: '*' 345 | react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' 346 | peerDependenciesMeta: 347 | '@babel/core': 348 | optional: true 349 | babel-plugin-macros: 350 | optional: true 351 | 352 | tslib@2.8.1: 353 | resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} 354 | 355 | typescript@4.9.5: 356 | resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} 357 | engines: {node: '>=4.2.0'} 358 | hasBin: true 359 | 360 | snapshots: 361 | 362 | '@emnapi/runtime@1.3.1': 363 | dependencies: 364 | tslib: 2.8.1 365 | optional: true 366 | 367 | '@img/sharp-darwin-arm64@0.33.5': 368 | optionalDependencies: 369 | '@img/sharp-libvips-darwin-arm64': 1.0.4 370 | optional: true 371 | 372 | '@img/sharp-darwin-x64@0.33.5': 373 | optionalDependencies: 374 | '@img/sharp-libvips-darwin-x64': 1.0.4 375 | optional: true 376 | 377 | '@img/sharp-libvips-darwin-arm64@1.0.4': 378 | optional: true 379 | 380 | '@img/sharp-libvips-darwin-x64@1.0.4': 381 | optional: true 382 | 383 | '@img/sharp-libvips-linux-arm64@1.0.4': 384 | optional: true 385 | 386 | '@img/sharp-libvips-linux-arm@1.0.5': 387 | optional: true 388 | 389 | '@img/sharp-libvips-linux-s390x@1.0.4': 390 | optional: true 391 | 392 | '@img/sharp-libvips-linux-x64@1.0.4': 393 | optional: true 394 | 395 | '@img/sharp-libvips-linuxmusl-arm64@1.0.4': 396 | optional: true 397 | 398 | '@img/sharp-libvips-linuxmusl-x64@1.0.4': 399 | optional: true 400 | 401 | '@img/sharp-linux-arm64@0.33.5': 402 | optionalDependencies: 403 | '@img/sharp-libvips-linux-arm64': 1.0.4 404 | optional: true 405 | 406 | '@img/sharp-linux-arm@0.33.5': 407 | optionalDependencies: 408 | '@img/sharp-libvips-linux-arm': 1.0.5 409 | optional: true 410 | 411 | '@img/sharp-linux-s390x@0.33.5': 412 | optionalDependencies: 413 | '@img/sharp-libvips-linux-s390x': 1.0.4 414 | optional: true 415 | 416 | '@img/sharp-linux-x64@0.33.5': 417 | optionalDependencies: 418 | '@img/sharp-libvips-linux-x64': 1.0.4 419 | optional: true 420 | 421 | '@img/sharp-linuxmusl-arm64@0.33.5': 422 | optionalDependencies: 423 | '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 424 | optional: true 425 | 426 | '@img/sharp-linuxmusl-x64@0.33.5': 427 | optionalDependencies: 428 | '@img/sharp-libvips-linuxmusl-x64': 1.0.4 429 | optional: true 430 | 431 | '@img/sharp-wasm32@0.33.5': 432 | dependencies: 433 | '@emnapi/runtime': 1.3.1 434 | optional: true 435 | 436 | '@img/sharp-win32-ia32@0.33.5': 437 | optional: true 438 | 439 | '@img/sharp-win32-x64@0.33.5': 440 | optional: true 441 | 442 | '@next/env@15.0.3': {} 443 | 444 | '@next/mdx@15.0.3': 445 | dependencies: 446 | source-map: 0.7.4 447 | 448 | '@next/swc-darwin-arm64@15.0.3': 449 | optional: true 450 | 451 | '@next/swc-darwin-x64@15.0.3': 452 | optional: true 453 | 454 | '@next/swc-linux-arm64-gnu@15.0.3': 455 | optional: true 456 | 457 | '@next/swc-linux-arm64-musl@15.0.3': 458 | optional: true 459 | 460 | '@next/swc-linux-x64-gnu@15.0.3': 461 | optional: true 462 | 463 | '@next/swc-linux-x64-musl@15.0.3': 464 | optional: true 465 | 466 | '@next/swc-win32-arm64-msvc@15.0.3': 467 | optional: true 468 | 469 | '@next/swc-win32-x64-msvc@15.0.3': 470 | optional: true 471 | 472 | '@swc/counter@0.1.3': {} 473 | 474 | '@swc/helpers@0.5.13': 475 | dependencies: 476 | tslib: 2.8.1 477 | 478 | '@types/node@18.11.18': {} 479 | 480 | '@types/prop-types@15.7.13': {} 481 | 482 | '@types/react-dom@18.0.10': 483 | dependencies: 484 | '@types/react': 18.2.8 485 | 486 | '@types/react@18.2.8': 487 | dependencies: 488 | '@types/prop-types': 15.7.13 489 | '@types/scheduler': 0.23.0 490 | csstype: 3.1.3 491 | 492 | '@types/scheduler@0.23.0': {} 493 | 494 | busboy@1.6.0: 495 | dependencies: 496 | streamsearch: 1.1.0 497 | 498 | caniuse-lite@1.0.30001686: {} 499 | 500 | client-only@0.0.1: {} 501 | 502 | color-convert@2.0.1: 503 | dependencies: 504 | color-name: 1.1.4 505 | optional: true 506 | 507 | color-name@1.1.4: 508 | optional: true 509 | 510 | color-string@1.9.1: 511 | dependencies: 512 | color-name: 1.1.4 513 | simple-swizzle: 0.2.2 514 | optional: true 515 | 516 | color@4.2.3: 517 | dependencies: 518 | color-convert: 2.0.1 519 | color-string: 1.9.1 520 | optional: true 521 | 522 | csstype@3.1.3: {} 523 | 524 | detect-libc@2.0.3: 525 | optional: true 526 | 527 | is-arrayish@0.3.2: 528 | optional: true 529 | 530 | js-tokens@4.0.0: {} 531 | 532 | loose-envify@1.4.0: 533 | dependencies: 534 | js-tokens: 4.0.0 535 | 536 | nanoid@3.3.8: {} 537 | 538 | next@15.0.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0): 539 | dependencies: 540 | '@next/env': 15.0.3 541 | '@swc/counter': 0.1.3 542 | '@swc/helpers': 0.5.13 543 | busboy: 1.6.0 544 | caniuse-lite: 1.0.30001686 545 | postcss: 8.4.31 546 | react: 18.2.0 547 | react-dom: 18.2.0(react@18.2.0) 548 | styled-jsx: 5.1.6(react@18.2.0) 549 | optionalDependencies: 550 | '@next/swc-darwin-arm64': 15.0.3 551 | '@next/swc-darwin-x64': 15.0.3 552 | '@next/swc-linux-arm64-gnu': 15.0.3 553 | '@next/swc-linux-arm64-musl': 15.0.3 554 | '@next/swc-linux-x64-gnu': 15.0.3 555 | '@next/swc-linux-x64-musl': 15.0.3 556 | '@next/swc-win32-arm64-msvc': 15.0.3 557 | '@next/swc-win32-x64-msvc': 15.0.3 558 | sharp: 0.33.5 559 | transitivePeerDependencies: 560 | - '@babel/core' 561 | - babel-plugin-macros 562 | 563 | picocolors@1.1.1: {} 564 | 565 | postcss@8.4.31: 566 | dependencies: 567 | nanoid: 3.3.8 568 | picocolors: 1.1.1 569 | source-map-js: 1.2.1 570 | 571 | react-dom@18.2.0(react@18.2.0): 572 | dependencies: 573 | loose-envify: 1.4.0 574 | react: 18.2.0 575 | scheduler: 0.23.2 576 | 577 | react@18.2.0: 578 | dependencies: 579 | loose-envify: 1.4.0 580 | 581 | scheduler@0.23.2: 582 | dependencies: 583 | loose-envify: 1.4.0 584 | 585 | semver@7.6.3: 586 | optional: true 587 | 588 | sharp@0.33.5: 589 | dependencies: 590 | color: 4.2.3 591 | detect-libc: 2.0.3 592 | semver: 7.6.3 593 | optionalDependencies: 594 | '@img/sharp-darwin-arm64': 0.33.5 595 | '@img/sharp-darwin-x64': 0.33.5 596 | '@img/sharp-libvips-darwin-arm64': 1.0.4 597 | '@img/sharp-libvips-darwin-x64': 1.0.4 598 | '@img/sharp-libvips-linux-arm': 1.0.5 599 | '@img/sharp-libvips-linux-arm64': 1.0.4 600 | '@img/sharp-libvips-linux-s390x': 1.0.4 601 | '@img/sharp-libvips-linux-x64': 1.0.4 602 | '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 603 | '@img/sharp-libvips-linuxmusl-x64': 1.0.4 604 | '@img/sharp-linux-arm': 0.33.5 605 | '@img/sharp-linux-arm64': 0.33.5 606 | '@img/sharp-linux-s390x': 0.33.5 607 | '@img/sharp-linux-x64': 0.33.5 608 | '@img/sharp-linuxmusl-arm64': 0.33.5 609 | '@img/sharp-linuxmusl-x64': 0.33.5 610 | '@img/sharp-wasm32': 0.33.5 611 | '@img/sharp-win32-ia32': 0.33.5 612 | '@img/sharp-win32-x64': 0.33.5 613 | optional: true 614 | 615 | simple-swizzle@0.2.2: 616 | dependencies: 617 | is-arrayish: 0.3.2 618 | optional: true 619 | 620 | source-map-js@1.2.1: {} 621 | 622 | source-map@0.7.4: {} 623 | 624 | streamsearch@1.1.0: {} 625 | 626 | styled-jsx@5.1.6(react@18.2.0): 627 | dependencies: 628 | client-only: 0.0.1 629 | react: 18.2.0 630 | 631 | tslib@2.8.1: {} 632 | 633 | typescript@4.9.5: {} 634 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "noEmit": true, 14 | "esModuleInterop": true, 15 | "module": "esnext", 16 | "moduleResolution": "node", 17 | "resolveJsonModule": true, 18 | "isolatedModules": true, 19 | "jsx": "preserve", 20 | "incremental": true, 21 | "baseUrl": ".", 22 | "plugins": [ 23 | { 24 | "name": "next" 25 | } 26 | ] 27 | }, 28 | "include": [ 29 | "next-env.d.ts", 30 | "**/*.ts", 31 | "**/*.tsx", 32 | ".next/types/**/*.ts" 33 | ], 34 | "exclude": [ 35 | "node_modules" 36 | ] 37 | } 38 | --------------------------------------------------------------------------------