Skip to navigation

Hosting Static Sites and SPAs on Object Storage

IBEE Object Storage can serve static websites and single-page applications (SPAs) directly from a bucket. Combined with the CDN and a custom domain, you get global delivery, automatic HTTPS, and zero-server hosting for frontends built with React, Vue, Angular, Svelte, or plain HTML.

Before you begin

  • An active IBEE Solutions organization (Create an organization)
  • A built static site or SPA (output folder containing index.html)
  • An S3 credential for the bucket’s workspace (API Credentials)
  • AWS CLI or any S3-compatible tool installed locally
1

1. Build your site

Generate the production build for your framework. The output folder is what you’ll upload.

FrameworkBuild commandOutput folder
React (CRA)npm run buildbuild/
React (Vite)npm run builddist/
Next.js (static export)next build && next exportout/
Vuenpm run builddist/
Angularng build --configuration productiondist/<project>/
Svelte / SvelteKitnpm run buildbuild/
Plain HTML—your source folder
2

2. Create a bucket

Create a bucket. Keep Automatic location, or click Need a specific location? click here to pick one of the available sites.

New buckets are private. After creating it, open the bucket → Settings → General and turn on Public Access (Bucket policies → Public access).

Bucket name tip: match the bucket name to your domain (e.g., app.ibee.ai) for clarity. It does not affect functionality.

3

3. Configure the AWS CLI

Set up a profile pointing at IBEE Object Storage:

aws configure --profile ibee
# AWS Access Key ID: <your access key>
# AWS Secret Access Key: <your secret>
# Default region: us-east-1
# Default output format: json
4

4. Upload your build output

Sync the build folder to your bucket. Replace <bucket>, <workspace-id>, and ./dist with your values — the full endpoint is the S3 Endpoint shown when you created the credential:

aws s3 sync ./dist s3://<bucket>/ \
--endpoint-url https://<workspace-id>.blob.ibeestorage.com \
--profile ibee \
--acl public-read \
--delete

The --delete flag removes files from the bucket that no longer exist locally — useful for clean redeploys.

5

5. Set correct cache headers

SPAs and static sites benefit from aggressive caching for hashed assets and no caching for index.html. Re-upload index.html with a short TTL after the sync:

aws s3 cp ./dist/index.html s3://<bucket>/index.html \
--endpoint-url https://<workspace-id>.blob.ibeestorage.com \
--profile ibee \
--acl public-read \
--cache-control "no-cache, no-store, must-revalidate" \
--content-type "text/html"

This ensures users always get the latest index.html (which references new hashed asset filenames), while the hashed assets themselves can be cached for a year by the CDN.

6

6. Create a CDN distribution

Put a CDN in front of the bucket for HTTPS, custom domains, and global edge caching (CDN integration).

  • Origin Type: Object Storage Bucket → select your bucket
  • Cache Policy: Static Assets (1 year)

You’ll get a CDN URL like dl-abc123.cdn.ibee.ai.

SPA deep links: the portal doesn’t currently offer a default-root-object or SPA-fallback (error page) setting for CDN distributions. A direct request for a client-side route such as /dashboard/settings doesn’t match any object key and can return 404. Use hash-based routing (for example /#/dashboard/settings) so every route loads from index.html.

7

7. Add a custom domain

Add your domain (e.g., app.ibee.ai) to the CDN distribution (CDN integration). Then create a CNAME at your DNS provider:

TypeNameValue
CNAMEappdl-abc123.cdn.ibee.ai

SSL is auto-provisioned within a few minutes of DNS propagating.

Verify

Visit your custom domain — you should see your site over HTTPS. For SPAs, open a few routes directly (with hash routing, e.g. /#/about) to confirm they load.

curl -I https://app.ibee.ai
# HTTP/2 200
# content-type: text/html
# cache-control: no-cache, no-store, must-revalidate

Redeploying

Each deploy is a fresh sync:

npm run build
aws s3 sync ./dist s3://<bucket>/ \
--endpoint-url https://<workspace-id>.blob.ibeestorage.com \
--profile ibee --acl public-read --delete
aws s3 cp ./dist/index.html s3://<bucket>/index.html \
--endpoint-url https://<workspace-id>.blob.ibeestorage.com \
--profile ibee --acl public-read \
--cache-control "no-cache" --content-type "text/html"

If hashed asset filenames changed, the CDN serves the new index.html immediately (because of no-cache), which then references the new assets — no manual cache invalidation needed.

Troubleshooting

Site loads on CDN URL but not on custom domain DNS hasn’t propagated yet, or the CNAME points at the bucket instead of the CDN URL. Use dig app.ibee.ai CNAME +short to confirm it resolves to dl-*.cdn.ibee.ai.

SPA returns 404 on refresh of nested routes There’s no index.html fallback setting for CDN distributions in the portal. Switch the app to hash-based routing (see the SPA note under Step 6).

Stale content after redeploy Hashed asset filenames should bust caches automatically. If you’re seeing the old index.html, confirm the Cache-Control: no-cache header is set on it (Step 5).

Mixed content / blocked HTTP requests Ensure all internal API calls and asset URLs use HTTPS. Browsers block HTTP subresources on HTTPS pages.

CORS errors when calling APIs from the site Configure CORS on the API or the bucket (CORS).