diff --git a/README.md b/README.md
index d1bb34be..0af834b8 100644
--- a/README.md
+++ b/README.md
@@ -104,9 +104,10 @@ Application behavior can be changed by configuring the following environment var
#### Site behavior
- `NEXT_PUBLIC_GRID_HOMEPAGE = 1` shows grid layout on homepage
- `NEXT_PUBLIC_DEFAULT_THEME = light | dark` sets preferred initial theme (defaults to `system` when not configured)
-- `NEXT_PUBLIC_PRO_MODE = 1` enables higher quality image storage (results in increased storage usage)
-- `NEXT_PUBLIC_STATICALLY_OPTIMIZE_PAGES = 1` enables static optimization for pages, i.e., renders pages at build time (results in increased project usage)—⚠️ _Experimental_
-- `NEXT_PUBLIC_STATICALLY_OPTIMIZE_OG_IMAGES = 1` enables static optimization for OG images, i.e., renders images at build time (results in increased project usage)—⚠️ _Experimental_
+- `NEXT_PUBLIC_PRESERVE_ORIGINAL_UPLOADS = 1` do not optimize photo uploads before storing (⚠️ results in increased storage usage)
+- `NEXT_PUBLIC_STATICALLY_OPTIMIZE_PHOTOS = 1` enables static optimization for photo pages (p/[photoId]), i.e., renders pages at build time (results in increased project usage)
+- `NEXT_PUBLIC_STATICALLY_OPTIMIZE_PHOTO_OG_IMAGES = 1` enables static optimization for OG images, i.e., renders images at build time (results in increased project usage)
+- `NEXT_PUBLIC_STATICALLY_OPTIMIZE_PHOTO_CATEGORIES = 1` enables static optimization for photo categories (tag/[tag], shot-on/[make]/[model], etc.), i.e., renders pages at build time (results in increased project usage)
- `NEXT_PUBLIC_MATTE_PHOTOS = 1` constrains the size of each photo, and enables a surrounding border (potentially useful for photos with tall aspect ratios)
- `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 (⚠️ re-compresses uploaded images in order to remove GPS information)
diff --git a/src/admin/AdminPhotosClient.tsx b/src/admin/AdminPhotosClient.tsx
index 1da58678..c105eb5d 100644
--- a/src/admin/AdminPhotosClient.tsx
+++ b/src/admin/AdminPhotosClient.tsx
@@ -3,7 +3,10 @@
import PhotoUpload from '@/photo/PhotoUpload';
import { clsx } from 'clsx/lite';
import SiteGrid from '@/components/SiteGrid';
-import { AI_TEXT_GENERATION_ENABLED, PRO_MODE_ENABLED } from '@/site/config';
+import {
+ AI_TEXT_GENERATION_ENABLED,
+ PRESERVE_ORIGINAL_UPLOADS,
+} from '@/site/config';
import AdminPhotosTable from '@/admin/AdminPhotosTable';
import AdminPhotosTableInfinite from '@/admin/AdminPhotosTableInfinite';
import PathLoaderButton from '@/components/primitives/PathLoaderButton';
@@ -43,7 +46,7 @@ export default function AdminPhotosClient({
Promise<{ photoId: string }[]>) | undefined = undefined;
-if (STATICALLY_OPTIMIZED_OG_IMAGES && IS_PRODUCTION) {
+if (STATICALLY_OPTIMIZED_PHOTO_OG_IMAGES && IS_PRODUCTION) {
generateStaticParams = async () => {
const photos = await getPhotoIds({ limit: GENERATE_STATIC_PARAMS_LIMIT });
return photos.map(photoId => ({ photoId }));
diff --git a/src/app/p/[photoId]/page.tsx b/src/app/p/[photoId]/page.tsx
index decfb273..a84aa724 100644
--- a/src/app/p/[photoId]/page.tsx
+++ b/src/app/p/[photoId]/page.tsx
@@ -12,7 +12,7 @@ import {
} from '@/site/paths';
import PhotoDetailPage from '@/photo/PhotoDetailPage';
import { getPhotosNearIdCached } from '@/photo/cache';
-import { IS_PRODUCTION, STATICALLY_OPTIMIZED_PAGES } from '@/site/config';
+import { IS_PRODUCTION, STATICALLY_OPTIMIZED_PHOTOS } from '@/site/config';
import { getPhotoIds } from '@/photo/db/query';
import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db';
import { cache } from 'react';
@@ -25,7 +25,7 @@ const getPhotosNearIdCachedCached = cache((photoId: string) =>
export let generateStaticParams:
(() => Promise<{ photoId: string }[]>) | undefined = undefined;
-if (STATICALLY_OPTIMIZED_PAGES && IS_PRODUCTION) {
+if (STATICALLY_OPTIMIZED_PHOTOS && IS_PRODUCTION) {
generateStaticParams = async () => {
const photos = await getPhotoIds({ limit: GENERATE_STATIC_PARAMS_LIMIT });
return photos.map(photoId => ({ photoId }));
diff --git a/src/photo/server.ts b/src/photo/server.ts
index d5b9232e..6096da28 100644
--- a/src/photo/server.ts
+++ b/src/photo/server.ts
@@ -11,7 +11,7 @@ import { ExifData, ExifParserFactory } from 'ts-exif-parser';
import { PhotoFormData } from './form';
import { FilmSimulation } from '@/simulation';
import sharp, { Sharp } from 'sharp';
-import { GEO_PRIVACY_ENABLED, PRO_MODE_ENABLED } from '@/site/config';
+import { GEO_PRIVACY_ENABLED, PRESERVE_ORIGINAL_UPLOADS } from '@/site/config';
const IMAGE_WIDTH_RESIZE = 200;
const IMAGE_WIDTH_BLUR = 200;
@@ -169,5 +169,5 @@ export const removeGpsData = async (image: ArrayBuffer) =>
GPSHPositioningError: GPS_NULL_STRING,
},
})
- .toFormat('jpeg', { quality: PRO_MODE_ENABLED ? 95 : 80 })
+ .toFormat('jpeg', { quality: PRESERVE_ORIGINAL_UPLOADS ? 95 : 80 })
.toBuffer();
diff --git a/src/site/SiteChecklistClient.tsx b/src/site/SiteChecklistClient.tsx
index 7cadb46a..d7ed9734 100644
--- a/src/site/SiteChecklistClient.tsx
+++ b/src/site/SiteChecklistClient.tsx
@@ -54,8 +54,9 @@ export default function SiteChecklistClient({
isProModeEnabled,
isGridHomepageEnabled,
isStaticallyOptimized,
- arePagesStaticallyOptimized,
- areOGImagesStaticallyOptimized,
+ arePhotosStaticallyOptimized,
+ arePhotoOGImagesStaticallyOptimized,
+ arePhotoCategoriesStaticallyOptimized,
arePhotosMatted,
isBlurEnabled,
isGeoPrivacyEnabled,
@@ -469,15 +470,21 @@ export default function SiteChecklistClient({
Set environment variable to {'"1"'} to enable static optimization,
i.e., rendering pages and images at build time:
{renderSubStatus(
- arePagesStaticallyOptimized ? 'checked' : 'optional',
+ arePhotosStaticallyOptimized ? 'checked' : 'optional',
renderEnvVars(['NEXT_PUBLIC_STATICALLY_OPTIMIZE_PAGES']),
'translate-y-[3.5px]',
)}
{renderSubStatus(
- areOGImagesStaticallyOptimized ? 'checked' : 'optional',
+ arePhotoOGImagesStaticallyOptimized ? 'checked' : 'optional',
renderEnvVars(['NEXT_PUBLIC_STATICALLY_OPTIMIZE_OG_IMAGES']),
'translate-y-[3.5px]',
)}
+ {renderSubStatus(
+ arePhotoCategoriesStaticallyOptimized ? 'checked' : 'optional',
+ // eslint-disable-next-line max-len
+ renderEnvVars(['NEXT_PUBLIC_STATICALLY_OPTIMIZE_PHOTO_CATEGORIES']),
+ 'translate-y-[3.5px]',
+ )}