Skip to main content

ViteStaticSite

The ViteStaticSite construct is a higher level CDK construct that makes it easy to create a Vite single page app. It provides a simple way to build and deploy the site to an S3 bucket; setup a CloudFront CDN for fast content delivery; and configure a custom domain for the website URL.

It's designed to work with static sites built with Vite. It allows you to automatically set environment variables in your Vite app directly from the outputs of your SST app. And it can also create a .d.ts type definition file for the environment variables.

The ViteStaticSite construct internally extends the StaticSite construct with the following pre-configured defaults.

  • indexPage is set to index.html.
  • errorPage is set to redirect_to_index_page. So error pages are redirected to the index page.
  • buildCommand is npm run build.
  • buildOutput is the dist folder in your Vite app.
  • fileOptions sets the cache control to max-age=0,no-cache,no-store,must-revalidate for HTML files; and max-age=31536000,public,immutable for JS/CSS files.

Examples

Minimal Config

Deploys a Vite app in the path/to/src directory.

new ViteStaticSite(stack, "Site", {
path: "path/to/src",
});

Environment variables

The ViteStaticSite construct allows you to set the environment variables in your Vite app based on outputs from other constructs in your SST app. So you don't have to hard code the config from your backend. Let's look at how.

Vite supports setting build time environment variables. In your JS files this looks like:

src/App.js
console.log(import.meta.env.VITE_API_URL);
console.log(import.meta.env.VITE_USER_POOL_CLIENT);

You can pass these in directly from the construct.

new ViteStaticSite(stack, "Site", {
path: "path/to/src",
environment: {
VITE_API_URL: api.url,
VITE_USER_POOL_CLIENT: auth.cognitoUserPoolClient.userPoolClientId,
},
});

Where api.url or auth.cognitoUserPoolClient.userPoolClientId are coming from other constructs in your SST app.

Type definitions

SST also creates a type definition file for the environment variables in src/sst-env.d.ts.

/// <reference types="vite/client" />

interface ImportMetaEnv {
readonly VITE_API_URL: string
readonly VITE_USER_POOL_CLIENT: string
}

interface ImportMeta {
readonly env: ImportMetaEnv
}

This tells your editor the environment variables that are available and autocompletes them for you.

Vite environment variables autocomplete

You can also override the path for the generated type definitions file.

new ViteStaticSite(stack, "Site", {
path: "path/to/src",
environment: {
VITE_API_URL: api.url,
VITE_USER_POOL_CLIENT: auth.cognitoUserPoolClient.userPoolClientId,
},
typesPath: "types/my-env.d.ts",
});

While deploying

On sst deploy, the environment variables will first be replaced by placeholder values, {{ VITE_API_URL }} and {{ VITE_USER_POOL_CLIENT }}, when building the Vite app. And after the referenced resources have been created, the Api and User Pool in this case, the placeholders in the HTML and JS files will then be replaced with the actual values.

While developing

To use these values while developing, run sst start to start the Live Lambda Development environment.

npx sst start

Then in your Vite app to reference these variables, add the sst-env package.

npm install --save-dev @serverless-stack/static-site-env

And tweak the Vite dev script to:

package.json
"scripts": {
"dev": "sst-env -- vite",
"build": "vite build",
"preview": "vite preview"
},

Now you can start your Vite app as usualy and it'll have the environment variables from your SST app.

npm run dev

There are a couple of things happening behind the scenes here:

  1. The sst start command generates a file with the values specified by ViteStaticSite's environment prop.
  2. The sst-env CLI will traverse up the directories to look for the root of your SST app.
  3. It'll then find the file that's generated in step 1.
  4. It'll load these as environment variables before running the start command.
note

sst-env only works if the Vite app is located inside the SST app or inside one of its subdirectories. For example:

/
sst.json
vite-app/

Custom domains

You can also configure custom domains for your Vite app. SST supports domains that are shoted either on Route 53 or externally.

Using the basic config for a domain hosted on Route 53.

new ViteStaticSite(stack, "Site", {
path: "path/to/src",
customDomain: "domain.com",
});

For more custom domain examples, check out the StaticSite examples.

More examples

For more examples, refer to the StaticSite snippets.

Constructor

new ViteStaticSite(scope, id, props)

Parameters

ViteStaticSiteProps

buildCommand?

Type : string

The command for building the website

new ViteStaticSite(stack, "Site", {
buildCommand: "npm run build",
});

buildOutput?

Type : string

The directory with the content that will be uploaded to the S3 bucket. If a buildCommand is provided, this is usually where the build output is generated. The path is relative to the path where the website source is located.

new ViteStaticSite(stack, "Site", {
buildOutput: "dist",
});

customDomain?

Type : string | StaticSiteDomainProps

The customDomain for this website. SST supports domains that are hosted either on Route 53 or externally. Note that you can also migrate externally hosted domains to Route 53 by following this guide.

new ViteStaticSite(stack, "Site", {
path: "path/to/src",
customDomain: "domain.com",
});
new ViteStaticSite(stack, "Site", {
path: "path/to/src",
customDomain: {
domainName: "domain.com",
domainAlias: "www.domain.com",
hostedZone: "domain.com"
}
});

disablePlaceholder?

Type : boolean

Default : false

When running sst start, a placeholder site is deployed. This is to ensure that the site content remains unchanged, and subsequent sst start can start up quickly.

new ViteStaticSite(stack, "ReactSite", {
disablePlaceholder: true
});

environment?

Type : Record<string, string>

An object with the key being the environment variable name. Note, this requires your build tool to support build time environment variables.

new ViteStaticSite(stack, "ReactSite", {
environment: {
REACT_APP_API_URL: api.url,
REACT_APP_USER_POOL_CLIENT: auth.cognitoUserPoolClient.userPoolClientId,
},
});

errorPage?

Type : "redirect_to_index_page" | Omit<string, "redirect_to_index_page">

The error page behavior for this website. Takes either an HTML page.

404.html

Or the constant "redirect_to_index_page" to redirect to the index page. Note that, if the error pages are redirected to the index page, the HTTP status code is set to 200. This is necessary for single page apps, that handle 404 pages on the client side.

new ViteStaticSite(stack, "Site", {
errorPage: "redirect_to_index_page",
});

fileOptions?

Type : Array<StaticSiteFileOptions>

Pass in a list of file options to configure cache control for different files. Behind the scenes, the StaticSite construct uses a combination of the s3 cp and s3 sync commands to upload the website content to the S3 bucket. An s3 cp command is run for each file option block, and the options are passed in as the command options.

new ViteStaticSite(stack, "Site", {
buildOutput: "dist",
fileOptions: {
exclude: "*",
include: "*.js",
cacheControl: "max-age=31536000,public,immutable",
}
});

indexPage?

Type : string

Default : "index.html"

The name of the index page (e.g. "index.html") of the website.

new ViteStaticSite(stack, "Site", {
indexPage: "other-index.html",
});

path

Type : string

Path to the directory where the website source is located.

new ViteStaticSite(stack, "Site", {
path: "path/to/src",
});

purgeFiles?

Type : boolean

Default : true

While deploying, SST removes old files that no longer exist. Pass in false to keep the old files around.

new ViteStaticSite(stack, "ReactSite", {
purge: false
});

replaceValues?

Type : Array<StaticSiteReplaceProps>

Pass in a list of placeholder values to be replaced in the website content. For example, the follow configuration:

new ViteStaticSite(stack, "ReactSite", {
replaceValues: [
{
files: "*.js",
search: "{{ API_URL }}",
replace: api.url,
},
{
files: "*.js",
search: "{{ COGNITO_USER_POOL_CLIENT_ID }}",
replace: auth.cognitoUserPoolClient.userPoolClientId,
},
],
});

typesPath?

Type : string

Default : "src/sst-env.d.ts"

The path where code-gen should place the type definition for environment variables

new ViteStaticSite(stack, "Site", {
typesFile: "./other/path/sst-env.d.ts",
})

waitForInvalidation?

Type : boolean

Default : true

While deploying, SST waits for the CloudFront cache invalidation process to finish. This ensures that the new content will be served once the deploy command finishes. However, this process can sometimes take more than 5 mins. For non-prod environments it might make sense to pass in false. That'll skip waiting for the cache to invalidate and speed up the deploy process.

new ViteStaticSite(stack, "ReactSite", {
waitForInvalidation: false
});

cdk.bucket?

Type : BucketProps | IBucket

Allows you to override default settings this construct uses internally to ceate the bucket

new ViteStaticSite(stack, "Site", {
path: "path/to/src",
cdk: {
bucket: {
bucketName: "mybucket",
},
}
});

cdk.distribution?

Type : StaticSiteCdkDistributionProps

Configure the internally created CDK Distribution instance.

new ViteStaticSite(stack, "Site", {
path: "path/to/src",
cdk: {
distribution: {
comment: "Distribution for my React website",
},
}
});

Properties

An instance of ViteStaticSite has the following properties.

bucketArn

Type : string

The ARN of the internally created S3 Bucket.

bucketName

Type : string

The name of the internally created S3 Bucket.

customDomainUrl

Type : undefined | string

If the custom domain is enabled, this is the URL of the website with the custom domain.

distributionDomain

Type : string

The domain name of the internally created CloudFront Distribution.

distributionId

Type : string

The ID of the internally created CloudFront Distribution.

url

Type : string

The CloudFront URL of the website.

cdk.bucket

Type : Bucket

The internally created CDK Bucket instance.

cdk.certificate?

Type : ICertificate

cdk.distribution

Type : Distribution

The internally created CDK Distribution instance.

cdk.hostedZone?

Type : IHostedZone

The Route 53 hosted zone for the custom domain.

Methods

An instance of ViteStaticSite has the following methods.

getConstructMetadata

getConstructMetadata()