Lighting Lab builds as a static site and is configured for deployment under:
https://paulhutchinson.me/lighting-lab/
The Vite base path is already set to /lighting-lab/, so the generated asset URLs point at that subpath.
Since paulhutchinson.me is hosted on AWS S3, the recommended deployment path for this project is:
- build locally
- sync the build output to the
lighting-lab/prefix in your website bucket - optionally invalidate CloudFront if your site sits behind it
This repo already defaults to your current website infrastructure:
- bucket:
paulhutchinson-me-site - prefix:
lighting-lab - region:
ap-northeast-1
Use the built-in deploy script for repeatable releases:
npm run deployThat command:
- Builds the project
- Verifies that
dist/exists - Uploads or copies the built files into the directory that serves
/lighting-lab/
You can run npm run deploy without creating .env.deploy if you want to use the default S3 bucket, prefix, and region above.
That is the intended path for this repo.
Create .env.deploy only if you want to override those defaults or add optional settings like CloudFront invalidation. To do that, copy the example file:
cp .env.deploy.example .env.deployOn PowerShell, the equivalent command is:
Copy-Item .env.deploy.example .env.deployThen fill in the values for one of the supported deployment modes.
Use this when your personal website is hosted from S3, which is the intended setup for Lighting Lab.
Example .env.deploy:
LIGHTING_LAB_DEPLOY_MODE=s3
LIGHTING_LAB_DEPLOY_S3_BUCKET=paulhutchinson-me-site
LIGHTING_LAB_DEPLOY_S3_PREFIX=lighting-lab
LIGHTING_LAB_DEPLOY_AWS_PROFILE=personal
LIGHTING_LAB_DEPLOY_AWS_REGION=ap-northeast-1
LIGHTING_LAB_DEPLOY_CLOUDFRONT_DISTRIBUTION_ID=EXAMPLE123
The deploy script will:
- run
npm run build - sync
dist/tos3://<bucket>/lighting-lab/ - upload
index.htmlwith no-cache headers - upload hashed assets with long-lived cache headers
- optionally create a CloudFront invalidation when a distribution ID is configured
This mode expects the AWS CLI to be installed and authenticated on your machine.
If aws is not on your PATH, the deploy script now fails early with a clear error before attempting upload commands.
If you want automatic invalidation, add:
LIGHTING_LAB_DEPLOY_CLOUDFRONT_DISTRIBUTION_ID=YOUR_DISTRIBUTION_ID
You can source that value from the CF_DISTRIBUTION_ID used by the personal site repo.
If your AWS CLI is already authenticated against the account that owns paulhutchinson-me-site, you can usually publish with:
npm run deployThe script will print the resolved bucket, prefix, region, and public URL before it uploads anything.
Your personal site repo currently deploys its root build with:
aws s3 sync "$SITE_DIR" "s3://$S3_BUCKET" --deleteThat means a normal deploy of paulhutchinson.me would remove lighting-lab/ unless the workflow explicitly excludes that prefix.
In the personal site repo, update the main S3 sync step to preserve the sub-app:
aws s3 sync "$SITE_DIR" "s3://$S3_BUCKET" \
--delete \
--exclude "index.html" \
--exclude "lighting-lab/*" \
--cache-control "public,max-age=31536000,immutable"Without that exclusion, Lighting Lab can deploy successfully and still disappear the next time the main site is published.
Use the trailing-slash form when linking publicly:
https://paulhutchinson.me/lighting-lab/
That maps cleanly to lighting-lab/index.html in the bucket and avoids ambiguity around the bare /lighting-lab path.
Use this when your personal website is hosted on a server you can access over SSH.
Example .env.deploy:
LIGHTING_LAB_DEPLOY_MODE=ssh
LIGHTING_LAB_DEPLOY_HOST=example.com
LIGHTING_LAB_DEPLOY_USER=deploy
LIGHTING_LAB_DEPLOY_PORT=22
LIGHTING_LAB_DEPLOY_PATH=/var/www/html/lighting-lab
The deploy script will:
- run
npm run build - create the remote target directory if needed
- upload the contents of
dist/withscp
This mode expects ssh and scp to be available on your machine.
Use this when your personal website files live on the same machine and /lighting-lab/ is just a local folder inside that site.
Example .env.deploy:
LIGHTING_LAB_DEPLOY_MODE=local
LIGHTING_LAB_DEPLOY_LOCAL_PATH=C:\path\to\your\site\lighting-lab
The deploy script will:
- run
npm run build - create the target directory if needed
- copy the built files into that directory
If you already have a fresh dist/ folder and only want to publish it, you can set:
LIGHTING_LAB_DEPLOY_SKIP_BUILD=true
That makes npm run deploy reuse the existing build output instead of rebuilding first.
- The deploy script overwrites files with the same names but does not delete old hashed assets from previous releases.
- In
s3mode,aws s3 sync --deleteremoves old files from the target prefix before cache headers are refreshed. - The remaining
LIGHTING_LAB_DEPLOY_SKIP_BUILD=trueoption is useful if you already have a known-gooddist/. - The app now lazy-loads the 3D preview, so the sidebar and shell render first while the heavier tower runtime streams in.