├── .gitignore ├── README.md ├── app ├── [[...slug]] │ ├── client.tsx │ └── page.tsx ├── favicon.ico ├── layout.tsx └── robots.txt ├── next.config.mjs ├── package.json ├── pnpm-lock.yaml ├── public └── logo.svg ├── src ├── App.css ├── App.js ├── App.test.js ├── index.css └── setupTests.js └── 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 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | # Next.js 26 | .next 27 | next-env.d.ts 28 | dist -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Migrating from Create React App to Next.js. 2 | 3 | This repository shows an example of migrating from CRA to Next.js. 4 | 5 | [View the commit](https://github.com/leerob/cra-to-next/commit/48273654f5d02875a1a993a8343f5ef8ffa21869) to [read the documentation](https://nextjs.org/docs/pages/building-your-application/upgrading/from-create-react-app). 6 | 7 | ## Example 8 | 9 | https://cra-next-example.vercel.app 10 | 11 | ![PageSpeed Insights Result](https://github.com/vercel/next.js/assets/9113740/a9e54fef-5100-40a6-8f7a-8fd80fb7528a) 12 | -------------------------------------------------------------------------------- /app/[[...slug]]/client.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import React from 'react'; 4 | import dynamic from 'next/dynamic'; 5 | 6 | const App = dynamic(() => import('../../src/App'), { ssr: false }); 7 | 8 | export function ClientOnly() { 9 | return ; 10 | } 11 | -------------------------------------------------------------------------------- /app/[[...slug]]/page.tsx: -------------------------------------------------------------------------------- 1 | import '../../src/index.css'; 2 | import { ClientOnly } from './client'; 3 | 4 | export function generateStaticParams() { 5 | return [{ slug: [''] }]; 6 | } 7 | 8 | export default function Page() { 9 | return ; 10 | } 11 | -------------------------------------------------------------------------------- /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vercel/cra-to-next/f12a248a5ac462b38e1d3b6816ea79041de9c93e/app/favicon.ico -------------------------------------------------------------------------------- /app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from 'next'; 2 | 3 | export const metadata: Metadata = { 4 | title: 'CRA to Next.js', 5 | description: 'Example of migrating CRA to Next.js as a SPA.', 6 | }; 7 | 8 | export default function RootLayout({ 9 | children, 10 | }: { 11 | children: React.ReactNode; 12 | }) { 13 | return ( 14 | 15 | 16 |
{children}
17 | 18 | 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /app/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | output: 'export', // Outputs a Single-Page Application (SPA). 4 | distDir: './dist', // Changes the build output directory to `./dist/`. 5 | }; 6 | 7 | export default nextConfig; 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "dependencies": { 4 | "next": "14.1.1-canary.38", 5 | "react": "^18.2.0", 6 | "react-dom": "^18.2.0" 7 | }, 8 | "scripts": { 9 | "dev": "next dev --turbo", 10 | "build": "next build", 11 | "start": "next start" 12 | }, 13 | "devDependencies": { 14 | "@types/node": "^20.11.17", 15 | "@types/react": "18.2.55", 16 | "@types/react-dom": "^18.2.19", 17 | "typescript": "^5.3.3" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '6.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | dependencies: 8 | next: 9 | specifier: 14.1.1-canary.38 10 | version: 14.1.1-canary.38(react-dom@18.2.0)(react@18.2.0) 11 | react: 12 | specifier: ^18.2.0 13 | version: 18.2.0 14 | react-dom: 15 | specifier: ^18.2.0 16 | version: 18.2.0(react@18.2.0) 17 | 18 | devDependencies: 19 | '@types/node': 20 | specifier: ^20.11.17 21 | version: 20.11.17 22 | '@types/react': 23 | specifier: 18.2.55 24 | version: 18.2.55 25 | '@types/react-dom': 26 | specifier: ^18.2.19 27 | version: 18.2.19 28 | typescript: 29 | specifier: ^5.3.3 30 | version: 5.3.3 31 | 32 | packages: 33 | 34 | /@emnapi/runtime@0.45.0: 35 | resolution: {integrity: sha512-Txumi3td7J4A/xTTwlssKieHKTGl3j4A1tglBx72auZ49YK7ePY6XZricgIg9mnZT4xPfA+UPCUdnhRuEFDL+w==} 36 | requiresBuild: true 37 | dependencies: 38 | tslib: 2.6.2 39 | dev: false 40 | optional: true 41 | 42 | /@img/sharp-darwin-arm64@0.33.2: 43 | resolution: {integrity: sha512-itHBs1rPmsmGF9p4qRe++CzCgd+kFYktnsoR1sbIAfsRMrJZau0Tt1AH9KVnufc2/tU02Gf6Ibujx+15qRE03w==} 44 | engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} 45 | cpu: [arm64] 46 | os: [darwin] 47 | requiresBuild: true 48 | optionalDependencies: 49 | '@img/sharp-libvips-darwin-arm64': 1.0.1 50 | dev: false 51 | optional: true 52 | 53 | /@img/sharp-darwin-x64@0.33.2: 54 | resolution: {integrity: sha512-/rK/69Rrp9x5kaWBjVN07KixZanRr+W1OiyKdXcbjQD6KbW+obaTeBBtLUAtbBsnlTTmWthw99xqoOS7SsySDg==} 55 | engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} 56 | cpu: [x64] 57 | os: [darwin] 58 | requiresBuild: true 59 | optionalDependencies: 60 | '@img/sharp-libvips-darwin-x64': 1.0.1 61 | dev: false 62 | optional: true 63 | 64 | /@img/sharp-libvips-darwin-arm64@1.0.1: 65 | resolution: {integrity: sha512-kQyrSNd6lmBV7O0BUiyu/OEw9yeNGFbQhbxswS1i6rMDwBBSX+e+rPzu3S+MwAiGU3HdLze3PanQ4Xkfemgzcw==} 66 | engines: {macos: '>=11', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} 67 | cpu: [arm64] 68 | os: [darwin] 69 | requiresBuild: true 70 | dev: false 71 | optional: true 72 | 73 | /@img/sharp-libvips-darwin-x64@1.0.1: 74 | resolution: {integrity: sha512-eVU/JYLPVjhhrd8Tk6gosl5pVlvsqiFlt50wotCvdkFGf+mDNBJxMh+bvav+Wt3EBnNZWq8Sp2I7XfSjm8siog==} 75 | engines: {macos: '>=10.13', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} 76 | cpu: [x64] 77 | os: [darwin] 78 | requiresBuild: true 79 | dev: false 80 | optional: true 81 | 82 | /@img/sharp-libvips-linux-arm64@1.0.1: 83 | resolution: {integrity: sha512-bnGG+MJjdX70mAQcSLxgeJco11G+MxTz+ebxlz8Y3dxyeb3Nkl7LgLI0mXupoO+u1wRNx/iRj5yHtzA4sde1yA==} 84 | engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} 85 | cpu: [arm64] 86 | os: [linux] 87 | requiresBuild: true 88 | dev: false 89 | optional: true 90 | 91 | /@img/sharp-libvips-linux-arm@1.0.1: 92 | resolution: {integrity: sha512-FtdMvR4R99FTsD53IA3LxYGghQ82t3yt0ZQ93WMZ2xV3dqrb0E8zq4VHaTOuLEAuA83oDawHV3fd+BsAPadHIQ==} 93 | engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} 94 | cpu: [arm] 95 | os: [linux] 96 | requiresBuild: true 97 | dev: false 98 | optional: true 99 | 100 | /@img/sharp-libvips-linux-s390x@1.0.1: 101 | resolution: {integrity: sha512-3+rzfAR1YpMOeA2zZNp+aYEzGNWK4zF3+sdMxuCS3ey9HhDbJ66w6hDSHDMoap32DueFwhhs3vwooAB2MaK4XQ==} 102 | engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} 103 | cpu: [s390x] 104 | os: [linux] 105 | requiresBuild: true 106 | dev: false 107 | optional: true 108 | 109 | /@img/sharp-libvips-linux-x64@1.0.1: 110 | resolution: {integrity: sha512-3NR1mxFsaSgMMzz1bAnnKbSAI+lHXVTqAHgc1bgzjHuXjo4hlscpUxc0vFSAPKI3yuzdzcZOkq7nDPrP2F8Jgw==} 111 | engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} 112 | cpu: [x64] 113 | os: [linux] 114 | requiresBuild: true 115 | dev: false 116 | optional: true 117 | 118 | /@img/sharp-libvips-linuxmusl-arm64@1.0.1: 119 | resolution: {integrity: sha512-5aBRcjHDG/T6jwC3Edl3lP8nl9U2Yo8+oTl5drd1dh9Z1EBfzUKAJFUDTDisDjUwc7N4AjnPGfCA3jl3hY8uDg==} 120 | engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} 121 | cpu: [arm64] 122 | os: [linux] 123 | requiresBuild: true 124 | dev: false 125 | optional: true 126 | 127 | /@img/sharp-libvips-linuxmusl-x64@1.0.1: 128 | resolution: {integrity: sha512-dcT7inI9DBFK6ovfeWRe3hG30h51cBAP5JXlZfx6pzc/Mnf9HFCQDLtYf4MCBjxaaTfjCCjkBxcy3XzOAo5txw==} 129 | engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} 130 | cpu: [x64] 131 | os: [linux] 132 | requiresBuild: true 133 | dev: false 134 | optional: true 135 | 136 | /@img/sharp-linux-arm64@0.33.2: 137 | resolution: {integrity: sha512-pz0NNo882vVfqJ0yNInuG9YH71smP4gRSdeL09ukC2YLE6ZyZePAlWKEHgAzJGTiOh8Qkaov6mMIMlEhmLdKew==} 138 | engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} 139 | cpu: [arm64] 140 | os: [linux] 141 | requiresBuild: true 142 | optionalDependencies: 143 | '@img/sharp-libvips-linux-arm64': 1.0.1 144 | dev: false 145 | optional: true 146 | 147 | /@img/sharp-linux-arm@0.33.2: 148 | resolution: {integrity: sha512-Fndk/4Zq3vAc4G/qyfXASbS3HBZbKrlnKZLEJzPLrXoJuipFNNwTes71+Ki1hwYW5lch26niRYoZFAtZVf3EGA==} 149 | engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} 150 | cpu: [arm] 151 | os: [linux] 152 | requiresBuild: true 153 | optionalDependencies: 154 | '@img/sharp-libvips-linux-arm': 1.0.1 155 | dev: false 156 | optional: true 157 | 158 | /@img/sharp-linux-s390x@0.33.2: 159 | resolution: {integrity: sha512-MBoInDXDppMfhSzbMmOQtGfloVAflS2rP1qPcUIiITMi36Mm5YR7r0ASND99razjQUpHTzjrU1flO76hKvP5RA==} 160 | engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} 161 | cpu: [s390x] 162 | os: [linux] 163 | requiresBuild: true 164 | optionalDependencies: 165 | '@img/sharp-libvips-linux-s390x': 1.0.1 166 | dev: false 167 | optional: true 168 | 169 | /@img/sharp-linux-x64@0.33.2: 170 | resolution: {integrity: sha512-xUT82H5IbXewKkeF5aiooajoO1tQV4PnKfS/OZtb5DDdxS/FCI/uXTVZ35GQ97RZXsycojz/AJ0asoz6p2/H/A==} 171 | engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} 172 | cpu: [x64] 173 | os: [linux] 174 | requiresBuild: true 175 | optionalDependencies: 176 | '@img/sharp-libvips-linux-x64': 1.0.1 177 | dev: false 178 | optional: true 179 | 180 | /@img/sharp-linuxmusl-arm64@0.33.2: 181 | resolution: {integrity: sha512-F+0z8JCu/UnMzg8IYW1TMeiViIWBVg7IWP6nE0p5S5EPQxlLd76c8jYemG21X99UzFwgkRo5yz2DS+zbrnxZeA==} 182 | engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} 183 | cpu: [arm64] 184 | os: [linux] 185 | requiresBuild: true 186 | optionalDependencies: 187 | '@img/sharp-libvips-linuxmusl-arm64': 1.0.1 188 | dev: false 189 | optional: true 190 | 191 | /@img/sharp-linuxmusl-x64@0.33.2: 192 | resolution: {integrity: sha512-+ZLE3SQmSL+Fn1gmSaM8uFusW5Y3J9VOf+wMGNnTtJUMUxFhv+P4UPaYEYT8tqnyYVaOVGgMN/zsOxn9pSsO2A==} 193 | engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} 194 | cpu: [x64] 195 | os: [linux] 196 | requiresBuild: true 197 | optionalDependencies: 198 | '@img/sharp-libvips-linuxmusl-x64': 1.0.1 199 | dev: false 200 | optional: true 201 | 202 | /@img/sharp-wasm32@0.33.2: 203 | resolution: {integrity: sha512-fLbTaESVKuQcpm8ffgBD7jLb/CQLcATju/jxtTXR1XCLwbOQt+OL5zPHSDMmp2JZIeq82e18yE0Vv7zh6+6BfQ==} 204 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} 205 | cpu: [wasm32] 206 | requiresBuild: true 207 | dependencies: 208 | '@emnapi/runtime': 0.45.0 209 | dev: false 210 | optional: true 211 | 212 | /@img/sharp-win32-ia32@0.33.2: 213 | resolution: {integrity: sha512-okBpql96hIGuZ4lN3+nsAjGeggxKm7hIRu9zyec0lnfB8E7Z6p95BuRZzDDXZOl2e8UmR4RhYt631i7mfmKU8g==} 214 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} 215 | cpu: [ia32] 216 | os: [win32] 217 | requiresBuild: true 218 | dev: false 219 | optional: true 220 | 221 | /@img/sharp-win32-x64@0.33.2: 222 | resolution: {integrity: sha512-E4magOks77DK47FwHUIGH0RYWSgRBfGdK56kIHSVeB9uIS4pPFr4N2kIVsXdQQo4LzOsENKV5KAhRlRL7eMAdg==} 223 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} 224 | cpu: [x64] 225 | os: [win32] 226 | requiresBuild: true 227 | dev: false 228 | optional: true 229 | 230 | /@next/env@14.1.1-canary.38: 231 | resolution: {integrity: sha512-rxdJzkQTmhElPwnYyd7K/k8IVbRM/aLf2Pk9zaXIZSvTTLizra7Y4hTPj5sXWdiMDEKLApdqjVH52XvQHGk4Ww==} 232 | dev: false 233 | 234 | /@next/swc-darwin-arm64@14.1.1-canary.38: 235 | resolution: {integrity: sha512-HEuQfbuxXKNVGlQk9JLNHhJoKgD8AOI7pNh5+meXq7csmLRG9MZPaQIEC7HckRmm5NyAmTbW7dX78Y5B1Hf8Jg==} 236 | engines: {node: '>= 10'} 237 | cpu: [arm64] 238 | os: [darwin] 239 | requiresBuild: true 240 | dev: false 241 | optional: true 242 | 243 | /@next/swc-darwin-x64@14.1.1-canary.38: 244 | resolution: {integrity: sha512-MDY2t9D785xN+GCsXMUG35DtrZzCrgz2HSwxR+3igtTOUeaKPK42o0AkcjwMP48TJ2TkHrMgTVbDSKRLmW3m/Q==} 245 | engines: {node: '>= 10'} 246 | cpu: [x64] 247 | os: [darwin] 248 | requiresBuild: true 249 | dev: false 250 | optional: true 251 | 252 | /@next/swc-linux-arm64-gnu@14.1.1-canary.38: 253 | resolution: {integrity: sha512-YLIq41/erjWMKvQ95S+J3H/SKknwa/7VR5LUCKgbV7QjTzbD7y7T3Df/bvIxFHXDSpSmJmi+eyPtq2T76u6big==} 254 | engines: {node: '>= 10'} 255 | cpu: [arm64] 256 | os: [linux] 257 | requiresBuild: true 258 | dev: false 259 | optional: true 260 | 261 | /@next/swc-linux-arm64-musl@14.1.1-canary.38: 262 | resolution: {integrity: sha512-5b1LIgJFq5Jwkmc/A04GMHbEuOOGUjqC9z+DFaLm67NztoO1Kof+ColYWdcuIgu1tSh7wf5j4dRfzMx/D/ulhw==} 263 | engines: {node: '>= 10'} 264 | cpu: [arm64] 265 | os: [linux] 266 | requiresBuild: true 267 | dev: false 268 | optional: true 269 | 270 | /@next/swc-linux-x64-gnu@14.1.1-canary.38: 271 | resolution: {integrity: sha512-+X3Jai2b07r61+1JUJGh8u/G+NGkHjAv6G3jt44t4VgaqbGN4J1AP0TMpExdEHIXucNvDt4KhlZeIIegkY6PWA==} 272 | engines: {node: '>= 10'} 273 | cpu: [x64] 274 | os: [linux] 275 | requiresBuild: true 276 | dev: false 277 | optional: true 278 | 279 | /@next/swc-linux-x64-musl@14.1.1-canary.38: 280 | resolution: {integrity: sha512-zZkW/sbifH6/3/nNE1ZMg/cXivfZX/d05UDfsfMfml+JJVUQH/mau/SRzOa7c7+A47epE1n0vQJlu01d4nSMSQ==} 281 | engines: {node: '>= 10'} 282 | cpu: [x64] 283 | os: [linux] 284 | requiresBuild: true 285 | dev: false 286 | optional: true 287 | 288 | /@next/swc-win32-arm64-msvc@14.1.1-canary.38: 289 | resolution: {integrity: sha512-igkTkSOQglhHrXPxUrjZnIwe8QZWGNnNQDH/xQLXIHcGD2xNAVp5fVYLOMC8yTRBs5v43+Xuvd2qfiQA/sq27w==} 290 | engines: {node: '>= 10'} 291 | cpu: [arm64] 292 | os: [win32] 293 | requiresBuild: true 294 | dev: false 295 | optional: true 296 | 297 | /@next/swc-win32-ia32-msvc@14.1.1-canary.38: 298 | resolution: {integrity: sha512-/ENeQ0tz6c//IBtj6vgau+1zlTJoaKd4cgP5nohEiSasWbrY3JjR3oEqFvuYL92mKY6bkrFB3zW3U0oI6OCc1Q==} 299 | engines: {node: '>= 10'} 300 | cpu: [ia32] 301 | os: [win32] 302 | requiresBuild: true 303 | dev: false 304 | optional: true 305 | 306 | /@next/swc-win32-x64-msvc@14.1.1-canary.38: 307 | resolution: {integrity: sha512-H6X52TMvDvP20I9agkF84CrAMFOovqXRvGJnhBrJbTfj5E219ApQKld7+WnQkc4rUv+x2ees2wnTHfwfdKcxhA==} 308 | engines: {node: '>= 10'} 309 | cpu: [x64] 310 | os: [win32] 311 | requiresBuild: true 312 | dev: false 313 | optional: true 314 | 315 | /@swc/counter@0.1.3: 316 | resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} 317 | dev: false 318 | 319 | /@swc/helpers@0.5.5: 320 | resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==} 321 | dependencies: 322 | '@swc/counter': 0.1.3 323 | tslib: 2.6.2 324 | dev: false 325 | 326 | /@types/node@20.11.17: 327 | resolution: {integrity: sha512-QmgQZGWu1Yw9TDyAP9ZzpFJKynYNeOvwMJmaxABfieQoVoiVOS6MN1WSpqpRcbeA5+RW82kraAVxCCJg+780Qw==} 328 | dependencies: 329 | undici-types: 5.26.5 330 | dev: true 331 | 332 | /@types/prop-types@15.7.11: 333 | resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==} 334 | dev: true 335 | 336 | /@types/react-dom@18.2.19: 337 | resolution: {integrity: sha512-aZvQL6uUbIJpjZk4U8JZGbau9KDeAwMfmhyWorxgBkqDIEf6ROjRozcmPIicqsUwPUjbkDfHKgGee1Lq65APcA==} 338 | dependencies: 339 | '@types/react': 18.2.55 340 | dev: true 341 | 342 | /@types/react@18.2.55: 343 | resolution: {integrity: sha512-Y2Tz5P4yz23brwm2d7jNon39qoAtMMmalOQv6+fEFt1mT+FcM3D841wDpoUvFXhaYenuROCy3FZYqdTjM7qVyA==} 344 | dependencies: 345 | '@types/prop-types': 15.7.11 346 | '@types/scheduler': 0.16.8 347 | csstype: 3.1.3 348 | dev: true 349 | 350 | /@types/scheduler@0.16.8: 351 | resolution: {integrity: sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==} 352 | dev: true 353 | 354 | /busboy@1.6.0: 355 | resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} 356 | engines: {node: '>=10.16.0'} 357 | dependencies: 358 | streamsearch: 1.1.0 359 | dev: false 360 | 361 | /caniuse-lite@1.0.30001584: 362 | resolution: {integrity: sha512-LOz7CCQ9M1G7OjJOF9/mzmqmj3jE/7VOmrfw6Mgs0E8cjOsbRXQJHsPBfmBOXDskXKrHLyyW3n7kpDW/4BsfpQ==} 363 | dev: false 364 | 365 | /client-only@0.0.1: 366 | resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} 367 | dev: false 368 | 369 | /color-convert@2.0.1: 370 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 371 | engines: {node: '>=7.0.0'} 372 | requiresBuild: true 373 | dependencies: 374 | color-name: 1.1.4 375 | dev: false 376 | optional: true 377 | 378 | /color-name@1.1.4: 379 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 380 | requiresBuild: true 381 | dev: false 382 | optional: true 383 | 384 | /color-string@1.9.1: 385 | resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} 386 | requiresBuild: true 387 | dependencies: 388 | color-name: 1.1.4 389 | simple-swizzle: 0.2.2 390 | dev: false 391 | optional: true 392 | 393 | /color@4.2.3: 394 | resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} 395 | engines: {node: '>=12.5.0'} 396 | requiresBuild: true 397 | dependencies: 398 | color-convert: 2.0.1 399 | color-string: 1.9.1 400 | dev: false 401 | optional: true 402 | 403 | /csstype@3.1.3: 404 | resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} 405 | dev: true 406 | 407 | /detect-libc@2.0.2: 408 | resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} 409 | engines: {node: '>=8'} 410 | requiresBuild: true 411 | dev: false 412 | optional: true 413 | 414 | /graceful-fs@4.2.11: 415 | resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} 416 | dev: false 417 | 418 | /is-arrayish@0.3.2: 419 | resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} 420 | requiresBuild: true 421 | dev: false 422 | optional: true 423 | 424 | /js-tokens@4.0.0: 425 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 426 | dev: false 427 | 428 | /loose-envify@1.4.0: 429 | resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} 430 | hasBin: true 431 | dependencies: 432 | js-tokens: 4.0.0 433 | dev: false 434 | 435 | /lru-cache@6.0.0: 436 | resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} 437 | engines: {node: '>=10'} 438 | requiresBuild: true 439 | dependencies: 440 | yallist: 4.0.0 441 | dev: false 442 | optional: true 443 | 444 | /nanoid@3.3.7: 445 | resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} 446 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 447 | hasBin: true 448 | dev: false 449 | 450 | /next@14.1.1-canary.38(react-dom@18.2.0)(react@18.2.0): 451 | resolution: {integrity: sha512-58D3IqyYbVqzmchFo0oGugarlgjOCHKy96VC39gxV1tF388Tj3BHq9H0Mc700D7QUJfyw6dnoG9suDbqIMps7g==} 452 | engines: {node: '>=18.17.0'} 453 | hasBin: true 454 | peerDependencies: 455 | '@opentelemetry/api': ^1.1.0 456 | react: ^18.2.0 457 | react-dom: ^18.2.0 458 | sass: ^1.3.0 459 | peerDependenciesMeta: 460 | '@opentelemetry/api': 461 | optional: true 462 | sass: 463 | optional: true 464 | dependencies: 465 | '@next/env': 14.1.1-canary.38 466 | '@swc/helpers': 0.5.5 467 | busboy: 1.6.0 468 | caniuse-lite: 1.0.30001584 469 | graceful-fs: 4.2.11 470 | postcss: 8.4.31 471 | react: 18.2.0 472 | react-dom: 18.2.0(react@18.2.0) 473 | styled-jsx: 5.1.1(react@18.2.0) 474 | optionalDependencies: 475 | '@next/swc-darwin-arm64': 14.1.1-canary.38 476 | '@next/swc-darwin-x64': 14.1.1-canary.38 477 | '@next/swc-linux-arm64-gnu': 14.1.1-canary.38 478 | '@next/swc-linux-arm64-musl': 14.1.1-canary.38 479 | '@next/swc-linux-x64-gnu': 14.1.1-canary.38 480 | '@next/swc-linux-x64-musl': 14.1.1-canary.38 481 | '@next/swc-win32-arm64-msvc': 14.1.1-canary.38 482 | '@next/swc-win32-ia32-msvc': 14.1.1-canary.38 483 | '@next/swc-win32-x64-msvc': 14.1.1-canary.38 484 | sharp: 0.33.2 485 | transitivePeerDependencies: 486 | - '@babel/core' 487 | - babel-plugin-macros 488 | dev: false 489 | 490 | /picocolors@1.0.0: 491 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} 492 | dev: false 493 | 494 | /postcss@8.4.31: 495 | resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} 496 | engines: {node: ^10 || ^12 || >=14} 497 | dependencies: 498 | nanoid: 3.3.7 499 | picocolors: 1.0.0 500 | source-map-js: 1.0.2 501 | dev: false 502 | 503 | /react-dom@18.2.0(react@18.2.0): 504 | resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} 505 | peerDependencies: 506 | react: ^18.2.0 507 | dependencies: 508 | loose-envify: 1.4.0 509 | react: 18.2.0 510 | scheduler: 0.23.0 511 | dev: false 512 | 513 | /react@18.2.0: 514 | resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} 515 | engines: {node: '>=0.10.0'} 516 | dependencies: 517 | loose-envify: 1.4.0 518 | dev: false 519 | 520 | /scheduler@0.23.0: 521 | resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} 522 | dependencies: 523 | loose-envify: 1.4.0 524 | dev: false 525 | 526 | /semver@7.6.0: 527 | resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} 528 | engines: {node: '>=10'} 529 | hasBin: true 530 | requiresBuild: true 531 | dependencies: 532 | lru-cache: 6.0.0 533 | dev: false 534 | optional: true 535 | 536 | /sharp@0.33.2: 537 | resolution: {integrity: sha512-WlYOPyyPDiiM07j/UO+E720ju6gtNtHjEGg5vovUk1Lgxyjm2LFO+37Nt/UI3MMh2l6hxTWQWi7qk3cXJTutcQ==} 538 | engines: {libvips: '>=8.15.1', node: ^18.17.0 || ^20.3.0 || >=21.0.0} 539 | requiresBuild: true 540 | dependencies: 541 | color: 4.2.3 542 | detect-libc: 2.0.2 543 | semver: 7.6.0 544 | optionalDependencies: 545 | '@img/sharp-darwin-arm64': 0.33.2 546 | '@img/sharp-darwin-x64': 0.33.2 547 | '@img/sharp-libvips-darwin-arm64': 1.0.1 548 | '@img/sharp-libvips-darwin-x64': 1.0.1 549 | '@img/sharp-libvips-linux-arm': 1.0.1 550 | '@img/sharp-libvips-linux-arm64': 1.0.1 551 | '@img/sharp-libvips-linux-s390x': 1.0.1 552 | '@img/sharp-libvips-linux-x64': 1.0.1 553 | '@img/sharp-libvips-linuxmusl-arm64': 1.0.1 554 | '@img/sharp-libvips-linuxmusl-x64': 1.0.1 555 | '@img/sharp-linux-arm': 0.33.2 556 | '@img/sharp-linux-arm64': 0.33.2 557 | '@img/sharp-linux-s390x': 0.33.2 558 | '@img/sharp-linux-x64': 0.33.2 559 | '@img/sharp-linuxmusl-arm64': 0.33.2 560 | '@img/sharp-linuxmusl-x64': 0.33.2 561 | '@img/sharp-wasm32': 0.33.2 562 | '@img/sharp-win32-ia32': 0.33.2 563 | '@img/sharp-win32-x64': 0.33.2 564 | dev: false 565 | optional: true 566 | 567 | /simple-swizzle@0.2.2: 568 | resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} 569 | requiresBuild: true 570 | dependencies: 571 | is-arrayish: 0.3.2 572 | dev: false 573 | optional: true 574 | 575 | /source-map-js@1.0.2: 576 | resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} 577 | engines: {node: '>=0.10.0'} 578 | dev: false 579 | 580 | /streamsearch@1.1.0: 581 | resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} 582 | engines: {node: '>=10.0.0'} 583 | dev: false 584 | 585 | /styled-jsx@5.1.1(react@18.2.0): 586 | resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} 587 | engines: {node: '>= 12.0.0'} 588 | peerDependencies: 589 | '@babel/core': '*' 590 | babel-plugin-macros: '*' 591 | react: '>= 16.8.0 || 17.x.x || ^18.0.0-0' 592 | peerDependenciesMeta: 593 | '@babel/core': 594 | optional: true 595 | babel-plugin-macros: 596 | optional: true 597 | dependencies: 598 | client-only: 0.0.1 599 | react: 18.2.0 600 | dev: false 601 | 602 | /tslib@2.6.2: 603 | resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} 604 | dev: false 605 | 606 | /typescript@5.3.3: 607 | resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} 608 | engines: {node: '>=14.17'} 609 | hasBin: true 610 | dev: true 611 | 612 | /undici-types@5.26.5: 613 | resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} 614 | dev: true 615 | 616 | /yallist@4.0.0: 617 | resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} 618 | requiresBuild: true 619 | dev: false 620 | optional: true 621 | -------------------------------------------------------------------------------- /public/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import './App.css'; 2 | 3 | function App() { 4 | return ( 5 |
6 |
7 | logo 8 |

9 | Edit src/App.js and save to reload. 10 |

11 | 17 | Learn React 18 | 19 |
20 |
21 | ); 22 | } 23 | 24 | export default App; 25 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /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": false, 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 | "baseUrl": ".", 21 | "incremental": true, 22 | "plugins": [ 23 | { 24 | "name": "next" 25 | } 26 | ], 27 | "strictNullChecks": true 28 | }, 29 | "include": [ 30 | "next-env.d.ts", 31 | "**/*.ts", 32 | "**/*.tsx", 33 | ".next/types/**/*.ts", 34 | "./dist/types/**/*.ts" 35 | ], 36 | "exclude": [ 37 | "node_modules" 38 | ] 39 | } 40 | --------------------------------------------------------------------------------