Skip to content

staticSite

View Source

Static sites in AWS combine S3 storage with CloudFront CDN for fast global content delivery. Stackattack creates static websites with custom domains, SSL certificates, and framework-specific routing (like Astro).

import * as saws from "@stackattack/aws";
const ctx = saws.context();
const storage = saws.bucket(ctx, { paths: ["./dist"] });
const site = saws.staticSite(ctx, {
bucket: storage,
domain: "example.com"
});
export const siteUrl = site.url;

After deploying a static site, you can manage it using:

AWS CLI:

Terminal window
# View CloudFront distribution details
aws cloudfront get-distribution --id E1234567890ABC
# Invalidate CloudFront cache after updating files
aws cloudfront create-invalidation --distribution-id E1234567890ABC --paths "/*"
# Check distribution status and configuration
aws cloudfront list-distributions --query 'DistributionList.Items[?Comment==`my-site`]'

Content Updates:

Terminal window
# Sync new files to S3 bucket
aws s3 sync ./dist s3://your-bucket-name --delete
# Invalidate specific files in CloudFront
aws cloudfront create-invalidation --distribution-id E1234567890ABC --paths "/index.html" "/css/*"

Custom Error Pages:

Terminal window
# Upload custom 404 page
aws s3 cp ./404.html s3://your-bucket-name/404.html

Framework-Specific Deployment:

// For Astro sites with proper routing
const site = saws.staticSite(ctx, {
bucket: storage,
domain: "example.com",
adapter: saws.astroAdapter()
});

Static sites work together with other Stackattack components:

  • bucket - Stores website files in S3
  • certificate - Provides SSL certificates for HTTPS domains

Static site costs are usage-based with significant free tiers:

  • S3 storage - ~$0.023/GB/month for file storage. A typical 100MB website costs ~$0.002/month.

  • CloudFront - First 1TB of data transfer out is free each month, then ~$0.085/GB. Includes:

    • Free tier: 10,000,000 HTTP requests/month
    • Free tier: 2,000,000 CloudFront Function invocations/month
    • Additional requests: ~$0.0075 per 10,000 requests
  • SSL certificate - Free through ACM when used with CloudFront.

  • Route53 DNS - ~$0.50/month per hosted zone + $0.40 per million queries.

  • Lambda@Edge (for advanced routing) - Only if used: ~$0.60 per million requests + compute time.

Typical monthly costs:

  • Small personal site (<1GB traffic): $0.50-2.00/month (mostly DNS)
  • Medium business site (<10GB traffic): $2-5/month
  • Large site (>50GB traffic): $5-15/month

Cost optimization strategies:

  • Use CloudFront caching effectively to reduce origin requests
  • Optimize images and assets to reduce storage and transfer costs
  • Set up proper Cache-Control headers for static assets
  • Consider using astroAdapter() for optimized caching of framework builds

See CloudFront Pricing for current rates.

Creates a complete static site hosting solution with S3, CloudFront, and Lambda@Edge.

function staticSite(ctx: Context, args: StaticSiteArgs): { distribution: Distribution; url: Output<string> }
  • ctx (Context) - The context for resource naming and tagging
  • args (StaticSiteArgs) - Configuration arguments for the static site
  • ({ distribution: Distribution; url: Output<string> }) - Creates a complete static site hosting solution with S3, CloudFront, and Lambda@Edge.

Creates a static site adapter configured for Astro framework conventions.

function astroAdapter(args?: AstroAdapterArgs): StaticSiteAdapter
  • (StaticSiteAdapter) - Creates a static site adapter configured for Astro framework conventions.

Static site adapter for a single-page application. This directs all requests to a single HTML page

function SPAAdapter(args?: SPAAdapterArgs): StaticSiteAdapter
  • (StaticSiteAdapter) - Static site adapter for a single-page application. This directs all requests to a single HTML page

Configuration arguments for the Astro static site adapter.

  • cacheControlMaxAge? (number) - Max age for patterns that match staticPaths
  • defaultHeaders? (Record<string, string>) - Default headers to include in every response from your CDN
  • headers? ({ headers: Record<string, Input<string>>; inherit?: boolean; patterns: string[] }[]) - A list of patterns and headers to include in response for keys that match each pattern
  • staticPaths? (string[]) - Custom file patterns that should receive long-term caching headers. By default, this includes “.jpg”, “.png”, “.apng”, “.avif”, “.gif”, “.webp”, “.js”, “.css”, and “*.svg”

Configuration arguments for the single page application static site adapter.

  • cacheControlMaxAge? (number) - Max age for patterns that match staticPaths
  • defaultHeaders? (Record<string, Input<string>>) - Default headers to include in every response
  • headers? ({ headers: Record<string, Input<string>>; inherit?: boolean; patterns: string[] }[]) - A list of patterns and headers to include in response for keys that match each pattern
  • index? (string) - The path to the HTML file for your single page application. Defaults to “index.html”
  • staticPaths? (string[]) - Custom file patterns that should receive long-term caching headers. By default, this includes “.jpg”, “.png”, “.apng”, “.avif”, “.gif”, “.webp”, “.js”, “.css”, and “*.svg”

Configuration interface for static site framework adapters.

  • defaultHeaders? (Record<string, Input<string>>) - Default headers to include in every response
  • errorPages? ({ code: number; key: string }[]) - Mapping of HTTP error codes to custom error page paths
  • getKey? ((uri: string) => string) - Function to transform URI paths to S3 object keys
  • getRedirectPath? ((uri: string) => string) - Function to get redirect path for domain redirects
  • headers? ({ headers: Record<string, Input<string>>; inherit?: boolean; patterns: string[] }[]) - A list of patterns and headers to include in response for keys that match each pattern
  • index? (string) - The default root page of your app, for example “index.html”. This will be served at the ”/” path

Configuration arguments for creating a static site with CloudFront distribution.

  • adapter? (StaticSiteAdapter) - Framework-specific adapter for routing and caching behavior
  • bucket (Input<BucketInput>) - The S3 bucket containing the static site files
  • certificate? (Input<string>) - ARN of existing SSL certificate (creates new one if not provided). Note that the certificate must be created in the us-east-1 region.
  • domain (Input<string>) - The primary domain name for the static site
  • headers? (Record<string, Input<string>>) - Response headers to include in every response for a file in the bucket
  • logsBucket? (null | Input<BucketInput>) - S3 bucket for CloudFront access logs (creates new one if undefined, disables if null)
  • logsPrefix? (Input<string>) - Prefix for CloudFront access log files
  • noBucketPolicy? (boolean) - Whether to skip creating the S3 bucket policy for CloudFront access
  • noPrefix? (boolean) - Whether to skip adding ‘static-site’ prefix to resource names
  • redirectDomains? (Input<string>[]) - Additional domains that should redirect to the primary domain
  • zoneId? (Input<string>) - Route53 hosted zone ID (auto-detected from domain if not provided)