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.
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.
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.
| File in this ZIP | Where it goes | What it does |
|---|---|---|
s3-directory-index-updater/index.mjss3-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.mjs | A 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.js | A 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 folder | Upload to s3://www.8k.art/beta/s3-cloudfront-indexer/ for public documentation/testing. | Public documentation package for the beta directory. |
www.8k.artbeta/https://8k.art/beta/.directory-index.jsonCLOUDFRONT_DISTRIBUTION_IDwww.8k.art.beta/.s3-cloudfront-indexer/.s3-cloudfront-indexer folder from this ZIP into beta/s3-cloudfront-indexer/.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.
This is the normal regional Lambda that listens to S3 changes.
directory, index, updater, or s3.s3-directory-index-updater/index.mjs.s3-directory-index-updater/package.json: @aws-sdk/client-s3 and @aws-sdk/client-cloudfront.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.
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.
www.8k.art.beta/. Use no prefix if you want all approved folders in the bucket handled.This is the function that CloudFront runs when someone opens a folder URL.
lambda-edge-directory-browser/index.mjs.$LATEST./beta* or the behavior serving your S3 public content.Event type: Origin request Lambda ARN: the new numbered version ARN Include body: No
cloudfront-function-headers/allow-all-cors-and-inline-text.js.https://8k.art/beta/ in Chrome.s3://www.8k.art/beta/, for example test-cache-invalidation.txt.https://8k.art/beta/. The new file should appear.https://8k.art/beta/. The deleted file should disappear.CreateInvalidation or invalidation path logs.CLOUDFRONT_DISTRIBUTION_ID is the 8k.art distribution ID, not a domain name.cloudfront:CreateInvalidation.$LATEST; publish a numbered version.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