> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.ibee.co.in/docs/infrastructure/object-storage/static-site-hosting/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ibee.co.in/_mcp/server. # Hosting Static Sites and SPAs on Object Storage > Complete guide to hosting static websites and single-page applications (React, Vue, Angular) on IBEE Object Storage with CDN, custom domains, and HTTPS. 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](/docs/getting-started/account-setup/create-a-project)) * A built static site or SPA (output folder containing `index.html`) * An S3 credential for the bucket's workspace ([API Credentials](/docs/infrastructure/object-storage/api-tokens)) * AWS CLI or any S3-compatible tool installed locally ### 1. Build your site Generate the production build for your framework. The output folder is what you'll upload. | Framework | Build command | Output folder | | ----------------------- | ------------------------------------- | ------------------ | | React (CRA) | `npm run build` | `build/` | | React (Vite) | `npm run build` | `dist/` | | Next.js (static export) | `next build && next export` | `out/` | | Vue | `npm run build` | `dist/` | | Angular | `ng build --configuration production` | `dist//` | | Svelte / SvelteKit | `npm run build` | `build/` | | Plain HTML | — | your source folder | ### 2. Create a bucket [Create a bucket](/docs/infrastructure/object-storage/buckets#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](/docs/infrastructure/object-storage/buckets/bucket-policies#public-access)). > **Info** > > **Bucket name tip:** match the bucket name to your domain (e.g., `app.ibee.ai`) for clarity. It does not affect functionality. ### 3. Configure the AWS CLI Set up a profile pointing at IBEE Object Storage: ```bash aws configure --profile ibee # AWS Access Key ID: # AWS Secret Access Key: # Default region: us-east-1 # Default output format: json ``` ### 4. Upload your build output Sync the build folder to your bucket. Replace ``, ``, and `./dist` with your values — the full endpoint is the **S3 Endpoint** shown when you created the credential: ```bash aws s3 sync ./dist s3:/// \ --endpoint-url https://.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. 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: ```bash aws s3 cp ./dist/index.html s3:///index.html \ --endpoint-url https://.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. Create a CDN distribution Put a CDN in front of the bucket for HTTPS, custom domains, and global edge caching ([CDN integration](/docs/infrastructure/object-storage/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`. > **Warning** > > **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. Add a custom domain Add your domain (e.g., `app.ibee.ai`) to the CDN distribution ([CDN integration](/docs/infrastructure/object-storage/cdn-integration)). Then create a CNAME at your DNS provider: | Type | Name | Value | | ----- | ----- | ----------------------- | | CNAME | `app` | `dl-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. ```bash 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: ```bash npm run build aws s3 sync ./dist s3:/// \ --endpoint-url https://.blob.ibeestorage.com \ --profile ibee --acl public-read --delete aws s3 cp ./dist/index.html s3:///index.html \ --endpoint-url https://.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](/docs/infrastructure/object-storage/buckets/cors)). ## Related pages * [Create a bucket](/docs/infrastructure/object-storage/buckets) * [Upload and download objects](/docs/infrastructure/object-storage/objects) * [CDN integration](/docs/infrastructure/object-storage/cdn-integration) * [Custom domains](/docs/infrastructure/object-storage/buckets/custom-domains) * [CORS](/docs/infrastructure/object-storage/buckets/cors) > Complete guide to hosting static websites and single-page applications (React, Vue, Angular) on IBEE Object Storage with CDN, custom domains, and HTTPS.