v96 update: larger sort headers for iPhone/iPad

The public directory table headers Name, Last modified, and Size are now much larger touch targets. Deploy lambda-edge-directory-browser/index.mjs to Lambda@Edge and publish a new version to make this visible on public directory pages.

START HERE — 8k.art S3 + CloudFront Directory Indexer

Purpose: This package makes S3 folders browseable like Apache folders through CloudFront, while allowing the directory pages and JSON indexes to be cached for a year and refreshed by CloudFront invalidation whenever S3 changes.

Do not improvise while tired or manic. Follow the numbered steps. Do not delete old Lambda versions, old CloudFront functions, old ZIPs, or the CloudFront distribution. Make one change, test it, then continue.

One-sentence architecture

S3 object events run the directory index updater Lambda, which rebuilds .directory-index.json files and invalidates CloudFront; the Lambda@Edge directory browser reads those JSON files and renders the public Apache-style folder page; the optional CloudFront Function normalizes headers and inline text display.

Where every important file goes

File in this ZIPWhere it goesWhat it does
s3-directory-index-updater/index.mjs
s3-directory-index-updater/package.json
A normal AWS Lambda function attached to S3 ObjectCreated/ObjectRemoved events for the public bucket, usually www.8k.art.Rebuilds .directory-index.json and creates CloudFront invalidations after uploads, overwrites, and deletes.
lambda-edge-directory-browser/index.mjsA Lambda@Edge function in us-east-1, attached to the CloudFront behavior as Origin request.Generates the browsable HTML page for folder URLs such as https://8k.art/beta/.
cloudfront-function-headers/allow-all-cors-and-inline-text.jsA CloudFront Function, usually associated with the behavior as Viewer response.Adds CORS/inline text headers so source/document files display nicely in the browser.
All .html, .txt, .json, and documentation files in this folderUpload to s3://www.8k.art/beta/s3-cloudfront-indexer/ for public documentation/testing.Public documentation package for the beta directory.

Critical settings you must know

Step 1 — Upload this documentation package to S3 for public testing

  1. Open the AWS Console.
  2. Go to S3.
  3. Open bucket www.8k.art.
  4. Open folder beta/.
  5. Create or open folder s3-cloudfront-indexer/.
  6. Upload the contents of the s3-cloudfront-indexer folder from this ZIP into beta/s3-cloudfront-indexer/.
  7. After upload, test: https://8k.art/beta/s3-cloudfront-indexer/

Important: This public upload is only the documentation/source package. The Lambda files still have to be deployed into AWS Lambda/CloudFront to change live behavior.

Step 2 — Deploy the S3 directory index updater Lambda

This is the normal regional Lambda that listens to S3 changes.

  1. Open AWS Lambda.
  2. Use the same region as your current updater Lambda, if one already exists.
  3. Find your existing S3 directory index updater Lambda. If you cannot find it, search for names containing directory, index, updater, or s3.
  4. Before changing it, copy its current code or download/export it as a backup.
  5. Replace the function code with this package's s3-directory-index-updater/index.mjs.
  6. Make sure the deployment package includes the dependencies in s3-directory-index-updater/package.json: @aws-sdk/client-s3 and @aws-sdk/client-cloudfront.
  7. Set or verify these environment variables:
CLOUDFRONT_DISTRIBUTION_ID=YOUR_8K_ART_DISTRIBUTION_ID
ENABLE_CLOUDFRONT_INVALIDATION=true
DIRECTORY_INDEX_CACHE_CONTROL=public, max-age=31536000, s-maxage=31536000, immutable
UPDATE_BUCKET_ROOT_INDEX=false

Minimum required value: CLOUDFRONT_DISTRIBUTION_ID. The others have safe defaults, but setting them makes the intended behavior obvious later.

Updater Lambda IAM permissions

The updater Lambda role needs S3 access for the public bucket and CloudFront invalidation permission. Use this package file as the template:

policies/s3-directory-index-updater-policy-example.json

Replace YOUR_BUCKET_NAME with www.8k.art.

S3 event trigger

  1. In the updater Lambda, open Configuration → Triggers.
  2. Add or verify an S3 trigger for bucket www.8k.art.
  3. Event types should include ObjectCreated and ObjectRemoved.
  4. Use a prefix if you only want this active under beta/. Use no prefix if you want all approved folders in the bucket handled.

Step 3 — Deploy the Lambda@Edge directory browser

This is the function that CloudFront runs when someone opens a folder URL.

  1. Open AWS Lambda.
  2. Switch region to us-east-1 / N. Virginia. Lambda@Edge must live there.
  3. Find your existing directory browser Lambda@Edge function.
  4. Backup the current code/version before changing it.
  5. Replace the code with lambda-edge-directory-browser/index.mjs.
  6. Deploy the function.
  7. Publish a new numbered version. Lambda@Edge cannot use $LATEST.
  8. Copy the new version ARN.
  9. Open CloudFront → Distributions → your 8k.art distribution → Behaviors.
  10. Edit the behavior that handles /beta* or the behavior serving your S3 public content.
  11. Under Function associations or Lambda function associations, set the Lambda@Edge association to:
Event type: Origin request
Lambda ARN: the new numbered version ARN
Include body: No
  1. Save changes and wait for CloudFront deployment to finish.

Step 4 — Deploy or verify the CloudFront Function header script

  1. Open CloudFront → Functions.
  2. Find the existing header/inline text function, or create one if needed.
  3. Paste in cloudfront-function-headers/allow-all-cors-and-inline-text.js.
  4. Save, test if desired, then publish.
  5. Associate it with the same CloudFront behavior as a Viewer response function, if that is how your distribution was set up before.

Step 5 — Test the whole system

  1. Open https://8k.art/beta/ in Chrome.
  2. Upload a tiny test file to s3://www.8k.art/beta/, for example test-cache-invalidation.txt.
  3. Wait for the updater Lambda to run. The coalescing delay may intentionally wait a few seconds to avoid S3 SlowDown during bulk uploads.
  4. Refresh https://8k.art/beta/. The new file should appear.
  5. Overwrite that same test file with different contents.
  6. Open the file through CloudFront and confirm the new contents appear after invalidation completes.
  7. Delete the test file.
  8. Refresh https://8k.art/beta/. The deleted file should disappear.

Step 6 — What to check if it does not update

Do-not-do list

Final success condition

You are done when this is true:

Upload / overwrite / delete a file in s3://www.8k.art/beta/
→ updater Lambda rebuilds .directory-index.json
→ updater Lambda creates CloudFront invalidation
→ https://8k.art/beta/ shows the current folder contents
→ unchanged pages can still cache for 365 days