diff --git a/README.md b/README.md
index be4000dc..eda4fcd4 100644
--- a/README.md
+++ b/README.md
@@ -90,6 +90,7 @@ _⚠️ READ BEFORE PROCEEDING_
Application behavior can be changed by configuring the following environment variables:
- `NEXT_PUBLIC_PRO_MODE = 1` enables higher quality image storage (results in increased storage usage)
+- `NEXT_PUBLIC_STATICALLY_OPTIMIZE = 1` enables PPR and static optimization, i.e., building pages ahead of time (results in increased storage usage)—⚠️ _Experimental_
- `NEXT_PUBLIC_BLUR_DISABLED = 1` prevents image blur data being stored and displayed (potentially useful for limiting Postgres usage)
- `NEXT_PUBLIC_GEO_PRIVACY = 1` disables collection/display of location-based data
- `NEXT_PUBLIC_IGNORE_PRIORITY_ORDER = 1` prevents `priority_order` field affecting photo order
diff --git a/next.config.js b/next.config.js
index f0ff1b30..4520e734 100644
--- a/next.config.js
+++ b/next.config.js
@@ -35,6 +35,16 @@ const nextConfig = {
.concat(createRemotePattern(HOSTNAME_AWS_S3)),
minimumCacheTTL: 31536000,
},
+ ...process.env.NEXT_PUBLIC_STATICALLY_OPTIMIZE === '1' && {
+ experimental: { ppr: true },
+ },
+ webpack: (config) => {
+ config.optimization ??= {};
+ if (process.env.NODE_ENV !== 'production') {
+ config.optimization.minimize = false;
+ }
+ return config;
+ },
};
const withBundleAnalyzer = require('@next/bundle-analyzer')({
diff --git a/package.json b/package.json
index 22c5f368..a088a2d2 100644
--- a/package.json
+++ b/package.json
@@ -42,7 +42,7 @@
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"nanoid": "^5.0.7",
- "next": "^14.2.3",
+ "next": "14.3.0-canary.29",
"next-auth": "5.0.0-beta.15",
"next-themes": "^0.3.0",
"openai": "^4.38.5",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 49a72494..d485f9cf 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -55,7 +55,7 @@ importers:
version: 1.1.3
'@vercel/analytics':
specifier: ^1.2.2
- version: 1.2.2(next@14.2.3(@babel/core@7.24.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
+ version: 1.2.2(next@14.3.0-canary.29(@babel/core@7.24.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
'@vercel/blob':
specifier: ^0.23.2
version: 0.23.2
@@ -67,7 +67,7 @@ importers:
version: 0.8.0
'@vercel/speed-insights':
specifier: ^1.0.10
- version: 1.0.10(next@14.2.3(@babel/core@7.24.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(svelte@4.2.15)(vue@3.4.25(typescript@5.4.5))
+ version: 1.0.10(next@14.3.0-canary.29(@babel/core@7.24.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(svelte@4.2.15)(vue@3.4.25(typescript@5.4.5))
ai:
specifier: ^3.0.34
version: 3.0.34(react@18.3.1)(solid-js@1.8.17)(svelte@4.2.15)(vue@3.4.25(typescript@5.4.5))(zod@3.23.4)
@@ -108,11 +108,11 @@ importers:
specifier: ^5.0.7
version: 5.0.7
next:
- specifier: ^14.2.3
- version: 14.2.3(@babel/core@7.24.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ specifier: 14.3.0-canary.29
+ version: 14.3.0-canary.29(@babel/core@7.24.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
next-auth:
specifier: 5.0.0-beta.15
- version: 5.0.0-beta.15(next@14.2.3(@babel/core@7.24.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
+ version: 5.0.0-beta.15(next@14.3.0-canary.29(@babel/core@7.24.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
next-themes:
specifier: ^0.3.0
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -540,6 +540,9 @@ packages:
resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==}
engines: {node: '>=10.0.0'}
+ '@emnapi/runtime@1.1.1':
+ resolution: {integrity: sha512-3bfqkzuR1KLx57nZfjr2NLnFOobvyS0aTszaEGCGqmYMVDRaGvgIZbjGSV/MHSSmLgQ/b9JFHQ5xm5WRZYd+XQ==}
+
'@eslint-community/eslint-utils@4.4.0':
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -588,6 +591,119 @@ packages:
'@humanwhocodes/object-schema@2.0.3':
resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==}
+ '@img/sharp-darwin-arm64@0.33.3':
+ resolution: {integrity: sha512-FaNiGX1MrOuJ3hxuNzWgsT/mg5OHG/Izh59WW2mk1UwYHUwtfbhk5QNKYZgxf0pLOhx9ctGiGa2OykD71vOnSw==}
+ 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'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-darwin-x64@0.33.3':
+ resolution: {integrity: sha512-2QeSl7QDK9ru//YBT4sQkoq7L0EAJZA3rtV+v9p8xTKl4U1bUqTIaCnoC7Ctx2kCjQgwFXDasOtPTCT8eCTXvw==}
+ 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'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-arm64@1.0.2':
+ resolution: {integrity: sha512-tcK/41Rq8IKlSaKRCCAuuY3lDJjQnYIW1UXU1kxcEKrfL8WR7N6+rzNoOxoQRJWTAECuKwgAHnPvqXGN8XfkHA==}
+ engines: {macos: '>=11', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-x64@1.0.2':
+ resolution: {integrity: sha512-Ofw+7oaWa0HiiMiKWqqaZbaYV3/UGL2wAPeLuJTx+9cXpCRdvQhCLG0IH8YGwM0yGWGLpsF4Su9vM1o6aer+Fw==}
+ engines: {macos: '>=10.13', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-linux-arm64@1.0.2':
+ resolution: {integrity: sha512-x7kCt3N00ofFmmkkdshwj3vGPCnmiDh7Gwnd4nUwZln2YjqPxV1NlTyZOvoDWdKQVDL911487HOueBvrpflagw==}
+ engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-arm@1.0.2':
+ resolution: {integrity: sha512-iLWCvrKgeFoglQxdEwzu1eQV04o8YeYGFXtfWU26Zr2wWT3q3MTzC+QTCO3ZQfWd3doKHT4Pm2kRmLbupT+sZw==}
+ engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [arm]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-s390x@1.0.2':
+ resolution: {integrity: sha512-cmhQ1J4qVhfmS6szYW7RT+gLJq9dH2i4maq+qyXayUSn9/3iY2ZeWpbAgSpSVbV2E1JUL2Gg7pwnYQ1h8rQIog==}
+ engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-x64@1.0.2':
+ resolution: {integrity: sha512-E441q4Qdb+7yuyiADVi5J+44x8ctlrqn8XgkDTwr4qPJzWkaHwD489iZ4nGDgcuya4iMN3ULV6NwbhRZJ9Z7SQ==}
+ engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.0.2':
+ resolution: {integrity: sha512-3CAkndNpYUrlDqkCM5qhksfE+qSIREVpyoeHIU6jd48SJZViAmznoQQLAv4hVXF7xyUB9zf+G++e2v1ABjCbEQ==}
+ engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-libvips-linuxmusl-x64@1.0.2':
+ resolution: {integrity: sha512-VI94Q6khIHqHWNOh6LLdm9s2Ry4zdjWJwH56WoiJU7NTeDwyApdZZ8c+SADC8OH98KWNQXnE01UdJ9CSfZvwZw==}
+ engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-linux-arm64@0.33.3':
+ resolution: {integrity: sha512-Zf+sF1jHZJKA6Gor9hoYG2ljr4wo9cY4twaxgFDvlG0Xz9V7sinsPp8pFd1XtlhTzYo0IhDbl3rK7P6MzHpnYA==}
+ 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'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-linux-arm@0.33.3':
+ resolution: {integrity: sha512-Q7Ee3fFSC9P7vUSqVEF0zccJsZ8GiiCJYGWDdhEjdlOeS9/jdkyJ6sUSPj+bL8VuOYFSbofrW0t/86ceVhx32w==}
+ 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'}
+ cpu: [arm]
+ os: [linux]
+
+ '@img/sharp-linux-s390x@0.33.3':
+ resolution: {integrity: sha512-vFk441DKRFepjhTEH20oBlFrHcLjPfI8B0pMIxGm3+yilKyYeHEVvrZhYFdqIseSclIqbQ3SnZMwEMWonY5XFA==}
+ 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'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@img/sharp-linux-x64@0.33.3':
+ resolution: {integrity: sha512-Q4I++herIJxJi+qmbySd072oDPRkCg/SClLEIDh5IL9h1zjhqjv82H0Seupd+q2m0yOfD+/fJnjSoDFtKiHu2g==}
+ 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'}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-linuxmusl-arm64@0.33.3':
+ resolution: {integrity: sha512-qnDccehRDXadhM9PM5hLvcPRYqyFCBN31kq+ErBSZtZlsAc1U4Z85xf/RXv1qolkdu+ibw64fUDaRdktxTNP9A==}
+ 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'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-linuxmusl-x64@0.33.3':
+ resolution: {integrity: sha512-Jhchim8kHWIU/GZ+9poHMWRcefeaxFIs9EBqf9KtcC14Ojk6qua7ghKiPs0sbeLbLj/2IGBtDcxHyjCdYWkk2w==}
+ 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'}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-wasm32@0.33.3':
+ resolution: {integrity: sha512-68zivsdJ0koE96stdUfM+gmyaK/NcoSZK5dV5CAjES0FUXS9lchYt8LAB5rTbM7nlWtxaU/2GON0HVN6/ZYJAQ==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [wasm32]
+
+ '@img/sharp-win32-ia32@0.33.3':
+ resolution: {integrity: sha512-CyimAduT2whQD8ER4Ux7exKrtfoaUiVr7HG0zZvO0XTFn2idUWljjxv58GxNTkFb8/J9Ub9AqITGkJD6ZginxQ==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@img/sharp-win32-x64@0.33.3':
+ resolution: {integrity: sha512-viT4fUIDKnli3IfOephGnolMzhz5VaTvDRkYqtZxOMIoMQ4MrAziO7pT1nVnOt2FAm7qW5aa+CCc13aEY6Le0g==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
+ cpu: [x64]
+ os: [win32]
+
'@isaacs/cliui@8.0.2':
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
engines: {node: '>=12'}
@@ -690,62 +806,62 @@ packages:
'@next/bundle-analyzer@14.2.3':
resolution: {integrity: sha512-Z88hbbngMs7njZKI8kTJIlpdLKYfMSLwnsqYe54AP4aLmgL70/Ynx/J201DQ+q2Lr6FxFw1uCeLGImDrHOl2ZA==}
- '@next/env@14.2.3':
- resolution: {integrity: sha512-W7fd7IbkfmeeY2gXrzJYDx8D2lWKbVoTIj1o1ScPHNzvp30s1AuoEFSdr39bC5sjxJaxTtq3OTCZboNp0lNWHA==}
+ '@next/env@14.3.0-canary.29':
+ resolution: {integrity: sha512-h5It2nnx97Y+VjVIEP+gLrQ/byTN34bAtHhdQui1fkdlsaBD/B7sjt6BITSJK4zk1IPztdoPHHaI8sMONVbeeg==}
'@next/eslint-plugin-next@14.2.3':
resolution: {integrity: sha512-L3oDricIIjgj1AVnRdRor21gI7mShlSwU/1ZGHmqM3LzHhXXhdkrfeNY5zif25Bi5Dd7fiJHsbhoZCHfXYvlAw==}
- '@next/swc-darwin-arm64@14.2.3':
- resolution: {integrity: sha512-3pEYo/RaGqPP0YzwnlmPN2puaF2WMLM3apt5jLW2fFdXD9+pqcoTzRk+iZsf8ta7+quAe4Q6Ms0nR0SFGFdS1A==}
+ '@next/swc-darwin-arm64@14.3.0-canary.29':
+ resolution: {integrity: sha512-ePqJ/d/7dYgdf+7YefmAdW08m5jysGw6PtB309fZbpm0BIUTLfSdShJKG+t6Ivft2jzYIwcfp3LoFHotG8XZTg==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
- '@next/swc-darwin-x64@14.2.3':
- resolution: {integrity: sha512-6adp7waE6P1TYFSXpY366xwsOnEXM+y1kgRpjSRVI2CBDOcbRjsJ67Z6EgKIqWIue52d2q/Mx8g9MszARj8IEA==}
+ '@next/swc-darwin-x64@14.3.0-canary.29':
+ resolution: {integrity: sha512-H/Ese4aLROI3V65DpzKDUUEPtyQir+oNAdrZM1PPFPTRDRMpHz2LvbdcsxQ/aeIkYfRAc+foj5unnFjpIdyFIg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
- '@next/swc-linux-arm64-gnu@14.2.3':
- resolution: {integrity: sha512-cuzCE/1G0ZSnTAHJPUT1rPgQx1w5tzSX7POXSLaS7w2nIUJUD+e25QoXD/hMfxbsT9rslEXugWypJMILBj/QsA==}
+ '@next/swc-linux-arm64-gnu@14.3.0-canary.29':
+ resolution: {integrity: sha512-hW1DOdQAw4oOV6rAwBZh4R1i24xYwjoXgAKHbz5BlVq9QFEW5Zku0srzSl4eDPG2VEgZWcFCkmMamqR+gZheJA==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
- '@next/swc-linux-arm64-musl@14.2.3':
- resolution: {integrity: sha512-0D4/oMM2Y9Ta3nGuCcQN8jjJjmDPYpHX9OJzqk42NZGJocU2MqhBq5tWkJrUQOQY9N+In9xOdymzapM09GeiZw==}
+ '@next/swc-linux-arm64-musl@14.3.0-canary.29':
+ resolution: {integrity: sha512-tn2OT3NUyd/B2q5jnwtbM2pta/r+eizQFgM8ZMxhGHsl0Md3qmCE8TqR6PjiTTipcrG7KP7qElxwWkyYiEGYIg==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
- '@next/swc-linux-x64-gnu@14.2.3':
- resolution: {integrity: sha512-ENPiNnBNDInBLyUU5ii8PMQh+4XLr4pG51tOp6aJ9xqFQ2iRI6IH0Ds2yJkAzNV1CfyagcyzPfROMViS2wOZ9w==}
+ '@next/swc-linux-x64-gnu@14.3.0-canary.29':
+ resolution: {integrity: sha512-S2EfPr1qbU2y/+dJPdnr3aJIOxS0vsYz+VDAccUdbmXhzM3RSdsaE0okZWztih8AmKiiCS69MFWo6hUKnlOL4A==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
- '@next/swc-linux-x64-musl@14.2.3':
- resolution: {integrity: sha512-BTAbq0LnCbF5MtoM7I/9UeUu/8ZBY0i8SFjUMCbPDOLv+un67e2JgyN4pmgfXBwy/I+RHu8q+k+MCkDN6P9ViQ==}
+ '@next/swc-linux-x64-musl@14.3.0-canary.29':
+ resolution: {integrity: sha512-DfTjNpx1Szk82LEHRq1u57tSjGBrg3+kgIfM5/O0OUdU+6ESEOdaLlf7YrD1gIu3k4lDfn37b4S7R/BmPme0tg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
- '@next/swc-win32-arm64-msvc@14.2.3':
- resolution: {integrity: sha512-AEHIw/dhAMLNFJFJIJIyOFDzrzI5bAjI9J26gbO5xhAKHYTZ9Or04BesFPXiAYXDNdrwTP2dQceYA4dL1geu8A==}
+ '@next/swc-win32-arm64-msvc@14.3.0-canary.29':
+ resolution: {integrity: sha512-C9Igll3rnPoRFgUUFCJMOQkmAFEDiQnVPO2tfxRyleXQP9jpSYY55PYpHGFOp6L0iNy8zc/PuznmR3pcS3E2fQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
- '@next/swc-win32-ia32-msvc@14.2.3':
- resolution: {integrity: sha512-vga40n1q6aYb0CLrM+eEmisfKCR45ixQYXuBXxOOmmoV8sYST9k7E3US32FsY+CkkF7NtzdcebiFT4CHuMSyZw==}
+ '@next/swc-win32-ia32-msvc@14.3.0-canary.29':
+ resolution: {integrity: sha512-5ItF8rCzPMFhG9mlcPl5YpccUyhj3G5ElkjacRJYnqok2GQVmXtu6Ot5+LEGT86TCpizzTx+NkkY/lBSu28RRw==}
engines: {node: '>= 10'}
cpu: [ia32]
os: [win32]
- '@next/swc-win32-x64-msvc@14.2.3':
- resolution: {integrity: sha512-Q1/zm43RWynxrO7lW4ehciQVj+5ePBhOK+/K2P7pLFX3JaJ/IZVC69SHidrmZSOkqz7ECIOhhy7XhAFG4JYyHA==}
+ '@next/swc-win32-x64-msvc@14.3.0-canary.29':
+ resolution: {integrity: sha512-Bjd22hlcK4Kf4/jqPz6GyRiZ+h2Oa/h64RnZFrAvFJJfpBBMIQlihYLoS6HRwdS+bAXPrlf6cOz4TLVdFnum4w==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
@@ -1245,11 +1361,8 @@ packages:
resolution: {integrity: sha512-IHk53BVw6MPMi2Gsn+hCng8rFA3ZmR3Rk7GllxDUW9qFJl/hiSvskn7XldkECapQVkIg/1dHpMAxI9xSTaLLSA==}
engines: {node: '>=14.0.0'}
- '@swc/counter@0.1.3':
- resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
-
- '@swc/helpers@0.5.5':
- resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==}
+ '@swc/helpers@0.5.11':
+ resolution: {integrity: sha512-YNlnKRWF2sVojTpIyzwou9XoTNbzbzONwRhOoniEioF1AtaitTvVZblaQRrAzChWQ1bLYyYSWzM18y4WwgzJ+A==}
'@tailwindcss/container-queries@0.1.1':
resolution: {integrity: sha512-p18dswChx6WnTSaJCSGx6lTmrGzNNvm2FtXmiO6AuA1V4U5REyoqwmT6kgAsIMdjo07QdAfYXHJ4hnMtfHzWgA==}
@@ -1907,6 +2020,13 @@ packages:
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+ color-string@1.9.1:
+ resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
+
+ color@4.2.3:
+ resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
+ engines: {node: '>=12.5.0'}
+
combined-stream@1.0.8:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
@@ -2042,6 +2162,10 @@ packages:
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
engines: {node: '>=6'}
+ detect-libc@2.0.3:
+ resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
+ engines: {node: '>=8'}
+
detect-newline@3.1.0:
resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==}
engines: {node: '>=8'}
@@ -2579,6 +2703,9 @@ packages:
is-arrayish@0.2.1:
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
+ is-arrayish@0.3.2:
+ resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
+
is-async-function@2.0.0:
resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==}
engines: {node: '>= 0.4'}
@@ -3133,8 +3260,8 @@ packages:
react: ^16.8 || ^17 || ^18
react-dom: ^16.8 || ^17 || ^18
- next@14.2.3:
- resolution: {integrity: sha512-dowFkFTR8v79NPJO4QsBUtxv0g9BrS/phluVpMAt2ku7H+cbcBJlopXjkWlwxrk/xGqMemr7JkGPGemPrLLX7A==}
+ next@14.3.0-canary.29:
+ resolution: {integrity: sha512-+4mx9dCIVBcW5jMs67jQ2ZCnb3VQ6AQPNBW6t8j17T+9Mp+h0c1XLzrCbfRETpDfdE0nfID2ilUYpQY/8oairg==}
engines: {node: '>=18.17.0'}
hasBin: true
peerDependencies:
@@ -3630,6 +3757,10 @@ packages:
resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==}
engines: {node: '>= 0.4'}
+ sharp@0.33.3:
+ resolution: {integrity: sha512-vHUeXJU1UvlO/BNwTpT0x/r53WkLUVxrmb5JTgW92fdFCFk0ispLMAeu/jPO2vjkXM1fYUi3K7/qcLF47pwM1A==}
+ engines: {libvips: '>=8.15.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+
shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
@@ -3649,6 +3780,9 @@ packages:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'}
+ simple-swizzle@0.2.2:
+ resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
+
sirv@2.0.4:
resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==}
engines: {node: '>= 10'}
@@ -4939,6 +5073,11 @@ snapshots:
'@discoveryjs/json-ext@0.5.7': {}
+ '@emnapi/runtime@1.1.1':
+ dependencies:
+ tslib: 2.6.2
+ optional: true
+
'@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)':
dependencies:
eslint: 8.57.0
@@ -4993,6 +5132,81 @@ snapshots:
'@humanwhocodes/object-schema@2.0.3': {}
+ '@img/sharp-darwin-arm64@0.33.3':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-arm64': 1.0.2
+ optional: true
+
+ '@img/sharp-darwin-x64@0.33.3':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-x64': 1.0.2
+ optional: true
+
+ '@img/sharp-libvips-darwin-arm64@1.0.2':
+ optional: true
+
+ '@img/sharp-libvips-darwin-x64@1.0.2':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm64@1.0.2':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm@1.0.2':
+ optional: true
+
+ '@img/sharp-libvips-linux-s390x@1.0.2':
+ optional: true
+
+ '@img/sharp-libvips-linux-x64@1.0.2':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.0.2':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-x64@1.0.2':
+ optional: true
+
+ '@img/sharp-linux-arm64@0.33.3':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm64': 1.0.2
+ optional: true
+
+ '@img/sharp-linux-arm@0.33.3':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm': 1.0.2
+ optional: true
+
+ '@img/sharp-linux-s390x@0.33.3':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-s390x': 1.0.2
+ optional: true
+
+ '@img/sharp-linux-x64@0.33.3':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-x64': 1.0.2
+ optional: true
+
+ '@img/sharp-linuxmusl-arm64@0.33.3':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-arm64': 1.0.2
+ optional: true
+
+ '@img/sharp-linuxmusl-x64@0.33.3':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-x64': 1.0.2
+ optional: true
+
+ '@img/sharp-wasm32@0.33.3':
+ dependencies:
+ '@emnapi/runtime': 1.1.1
+ optional: true
+
+ '@img/sharp-win32-ia32@0.33.3':
+ optional: true
+
+ '@img/sharp-win32-x64@0.33.3':
+ optional: true
+
'@isaacs/cliui@8.0.2':
dependencies:
string-width: 5.1.2
@@ -5202,37 +5416,37 @@ snapshots:
- bufferutil
- utf-8-validate
- '@next/env@14.2.3': {}
+ '@next/env@14.3.0-canary.29': {}
'@next/eslint-plugin-next@14.2.3':
dependencies:
glob: 10.3.10
- '@next/swc-darwin-arm64@14.2.3':
+ '@next/swc-darwin-arm64@14.3.0-canary.29':
optional: true
- '@next/swc-darwin-x64@14.2.3':
+ '@next/swc-darwin-x64@14.3.0-canary.29':
optional: true
- '@next/swc-linux-arm64-gnu@14.2.3':
+ '@next/swc-linux-arm64-gnu@14.3.0-canary.29':
optional: true
- '@next/swc-linux-arm64-musl@14.2.3':
+ '@next/swc-linux-arm64-musl@14.3.0-canary.29':
optional: true
- '@next/swc-linux-x64-gnu@14.2.3':
+ '@next/swc-linux-x64-gnu@14.3.0-canary.29':
optional: true
- '@next/swc-linux-x64-musl@14.2.3':
+ '@next/swc-linux-x64-musl@14.3.0-canary.29':
optional: true
- '@next/swc-win32-arm64-msvc@14.2.3':
+ '@next/swc-win32-arm64-msvc@14.3.0-canary.29':
optional: true
- '@next/swc-win32-ia32-msvc@14.2.3':
+ '@next/swc-win32-ia32-msvc@14.3.0-canary.29':
optional: true
- '@next/swc-win32-x64-msvc@14.2.3':
+ '@next/swc-win32-x64-msvc@14.3.0-canary.29':
optional: true
'@nodelib/fs.scandir@2.1.5':
@@ -5861,11 +6075,8 @@ snapshots:
'@smithy/types': 2.12.0
tslib: 2.6.2
- '@swc/counter@0.1.3': {}
-
- '@swc/helpers@0.5.5':
+ '@swc/helpers@0.5.11':
dependencies:
- '@swc/counter': 0.1.3
tslib: 2.6.2
'@tailwindcss/container-queries@0.1.1(tailwindcss@3.4.3)':
@@ -6157,11 +6368,11 @@ snapshots:
dependencies:
crypto-js: 4.2.0
- '@vercel/analytics@1.2.2(next@14.2.3(@babel/core@7.24.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
+ '@vercel/analytics@1.2.2(next@14.3.0-canary.29(@babel/core@7.24.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
dependencies:
server-only: 0.0.1
optionalDependencies:
- next: 14.2.3(@babel/core@7.24.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ next: 14.3.0-canary.29(@babel/core@7.24.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
'@vercel/blob@0.23.2':
@@ -6182,9 +6393,9 @@ snapshots:
utf-8-validate: 6.0.3
ws: 8.14.2(bufferutil@4.0.8)(utf-8-validate@6.0.3)
- '@vercel/speed-insights@1.0.10(next@14.2.3(@babel/core@7.24.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(svelte@4.2.15)(vue@3.4.25(typescript@5.4.5))':
+ '@vercel/speed-insights@1.0.10(next@14.3.0-canary.29(@babel/core@7.24.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(svelte@4.2.15)(vue@3.4.25(typescript@5.4.5))':
optionalDependencies:
- next: 14.2.3(@babel/core@7.24.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ next: 14.3.0-canary.29(@babel/core@7.24.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
svelte: 4.2.15
vue: 3.4.25(typescript@5.4.5)
@@ -6650,6 +6861,18 @@ snapshots:
color-name@1.1.4: {}
+ color-string@1.9.1:
+ dependencies:
+ color-name: 1.1.4
+ simple-swizzle: 0.2.2
+ optional: true
+
+ color@4.2.3:
+ dependencies:
+ color-convert: 2.0.1
+ color-string: 1.9.1
+ optional: true
+
combined-stream@1.0.8:
dependencies:
delayed-stream: 1.0.0
@@ -6768,6 +6991,9 @@ snapshots:
dequal@2.0.3: {}
+ detect-libc@2.0.3:
+ optional: true
+
detect-newline@3.1.0: {}
detect-node-es@1.1.0: {}
@@ -7456,6 +7682,9 @@ snapshots:
is-arrayish@0.2.1: {}
+ is-arrayish@0.3.2:
+ optional: true
+
is-async-function@2.0.0:
dependencies:
has-tostringtag: 1.0.2
@@ -8152,10 +8381,10 @@ snapshots:
natural-compare@1.4.0: {}
- next-auth@5.0.0-beta.15(next@14.2.3(@babel/core@7.24.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1):
+ next-auth@5.0.0-beta.15(next@14.3.0-canary.29(@babel/core@7.24.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1):
dependencies:
'@auth/core': 0.28.0
- next: 14.2.3(@babel/core@7.24.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ next: 14.3.0-canary.29(@babel/core@7.24.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
next-themes@0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
@@ -8163,10 +8392,10 @@ snapshots:
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
- next@14.2.3(@babel/core@7.24.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
+ next@14.3.0-canary.29(@babel/core@7.24.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
- '@next/env': 14.2.3
- '@swc/helpers': 0.5.5
+ '@next/env': 14.3.0-canary.29
+ '@swc/helpers': 0.5.11
busboy: 1.6.0
caniuse-lite: 1.0.30001612
graceful-fs: 4.2.11
@@ -8175,15 +8404,16 @@ snapshots:
react-dom: 18.3.1(react@18.3.1)
styled-jsx: 5.1.1(@babel/core@7.24.4)(react@18.3.1)
optionalDependencies:
- '@next/swc-darwin-arm64': 14.2.3
- '@next/swc-darwin-x64': 14.2.3
- '@next/swc-linux-arm64-gnu': 14.2.3
- '@next/swc-linux-arm64-musl': 14.2.3
- '@next/swc-linux-x64-gnu': 14.2.3
- '@next/swc-linux-x64-musl': 14.2.3
- '@next/swc-win32-arm64-msvc': 14.2.3
- '@next/swc-win32-ia32-msvc': 14.2.3
- '@next/swc-win32-x64-msvc': 14.2.3
+ '@next/swc-darwin-arm64': 14.3.0-canary.29
+ '@next/swc-darwin-x64': 14.3.0-canary.29
+ '@next/swc-linux-arm64-gnu': 14.3.0-canary.29
+ '@next/swc-linux-arm64-musl': 14.3.0-canary.29
+ '@next/swc-linux-x64-gnu': 14.3.0-canary.29
+ '@next/swc-linux-x64-musl': 14.3.0-canary.29
+ '@next/swc-win32-arm64-msvc': 14.3.0-canary.29
+ '@next/swc-win32-ia32-msvc': 14.3.0-canary.29
+ '@next/swc-win32-x64-msvc': 14.3.0-canary.29
+ sharp: 0.33.3
transitivePeerDependencies:
- '@babel/core'
- babel-plugin-macros
@@ -8646,6 +8876,33 @@ snapshots:
functions-have-names: 1.2.3
has-property-descriptors: 1.0.2
+ sharp@0.33.3:
+ dependencies:
+ color: 4.2.3
+ detect-libc: 2.0.3
+ semver: 7.6.0
+ optionalDependencies:
+ '@img/sharp-darwin-arm64': 0.33.3
+ '@img/sharp-darwin-x64': 0.33.3
+ '@img/sharp-libvips-darwin-arm64': 1.0.2
+ '@img/sharp-libvips-darwin-x64': 1.0.2
+ '@img/sharp-libvips-linux-arm': 1.0.2
+ '@img/sharp-libvips-linux-arm64': 1.0.2
+ '@img/sharp-libvips-linux-s390x': 1.0.2
+ '@img/sharp-libvips-linux-x64': 1.0.2
+ '@img/sharp-libvips-linuxmusl-arm64': 1.0.2
+ '@img/sharp-libvips-linuxmusl-x64': 1.0.2
+ '@img/sharp-linux-arm': 0.33.3
+ '@img/sharp-linux-arm64': 0.33.3
+ '@img/sharp-linux-s390x': 0.33.3
+ '@img/sharp-linux-x64': 0.33.3
+ '@img/sharp-linuxmusl-arm64': 0.33.3
+ '@img/sharp-linuxmusl-x64': 0.33.3
+ '@img/sharp-wasm32': 0.33.3
+ '@img/sharp-win32-ia32': 0.33.3
+ '@img/sharp-win32-x64': 0.33.3
+ optional: true
+
shebang-command@2.0.0:
dependencies:
shebang-regex: 3.0.0
@@ -8663,6 +8920,11 @@ snapshots:
signal-exit@4.1.0: {}
+ simple-swizzle@0.2.2:
+ dependencies:
+ is-arrayish: 0.3.2
+ optional: true
+
sirv@2.0.4:
dependencies:
'@polka/url': 1.0.0-next.25
diff --git a/src/app/loading.tsx b/src/app/loading.tsx
new file mode 100644
index 00000000..1ae6b757
--- /dev/null
+++ b/src/app/loading.tsx
@@ -0,0 +1 @@
+export { default } from '@/components/PageSpinner';
diff --git a/src/app/p/[photoId]/layout.tsx b/src/app/p/[photoId]/layout.tsx
index 4167b64c..a346eeab 100644
--- a/src/app/p/[photoId]/layout.tsx
+++ b/src/app/p/[photoId]/layout.tsx
@@ -1,4 +1,5 @@
import {
+ GENERATE_STATIC_PARAMS_LIMIT,
GRID_THUMBNAILS_TO_SHOW_MAX,
descriptionForPhoto,
titleForPhoto,
@@ -12,6 +13,18 @@ import {
} from '@/site/paths';
import PhotoDetailPage from '@/photo/PhotoDetailPage';
import { getPhotosNearIdCachedCached } from '@/photo/cache';
+import { STATICALLY_OPTIMIZED } from '@/site/config';
+import { getPhotoIds } from '@/services/vercel-postgres';
+
+export let generateStaticParams:
+ (() => Promise<{ photoId: string }[]>) | undefined = undefined;
+
+if (STATICALLY_OPTIMIZED) {
+ generateStaticParams = async () => {
+ const photos = await getPhotoIds({ limit: GENERATE_STATIC_PARAMS_LIMIT });
+ return photos.map(photoId => ({ photoId }));
+ };
+}
interface PhotoProps {
params: { photoId: string }
diff --git a/src/photo/index.ts b/src/photo/index.ts
index 2af0a08f..0c94abd5 100644
--- a/src/photo/index.ts
+++ b/src/photo/index.ts
@@ -13,6 +13,8 @@ import {
import camelcaseKeys from 'camelcase-keys';
import type { Metadata } from 'next';
+export const GENERATE_STATIC_PARAMS_LIMIT = 1000;
+
// ROOT PAGE
export const INFINITE_SCROLL_INITIAL_HOME =
process.env.NODE_ENV === 'development' ? 2 : 12;
diff --git a/src/site/SiteChecklistClient.tsx b/src/site/SiteChecklistClient.tsx
index c5f876e5..fea161ea 100644
--- a/src/site/SiteChecklistClient.tsx
+++ b/src/site/SiteChecklistClient.tsx
@@ -39,6 +39,7 @@ export default function SiteChecklistClient({
showFilmSimulations,
showExifInfo,
isProModeEnabled,
+ isStaticallyOptimized,
isBlurEnabled,
isGeoPrivacyEnabled,
isPriorityOrderEnabled,
@@ -333,6 +334,17 @@ export default function SiteChecklistClient({
higher quality image storage:
{renderEnvVars(['NEXT_PUBLIC_PRO_MODE'])}
+
+ Set environment variable to {'"1"'} to enable PPR
+ and static optimization, i.e., build pages ahead of time:
+ {renderEnvVars(['NEXT_PUBLIC_STATICALLY_OPTIMIZE'])}
+