Static Website Examples, Troubleshooting and Tips

This page shows examples, troubleshooting and tips for using buckets to host a static website.

Website configuration examples

The following scenarios demonstrate the objects that are served to you when you attempt to access them with various URLs.

Three-object bucket

Suppose a bucket named www.example.com has been configured as a website with the following settings and files:

  • MainPageSuffix = "index.html"
  • NotFoundPage = "404.html"
  • The bucket contains three publicly shared objects: "index.html", "404.html", and "dir/index.html".

The following table shows the content served for selected URLs:

URL Requested Content Served HTTP response code
http://www.example.com
http://www.example.com/
http://www.example.com/index.html
The object "index.html". 200
http://www.example.com/hello The object "404.html". 404
http://www.example.com/dir/index.html The object "dir/index.html". 200
http://www.example.com/dir The object "dir/index.html". 301
http://www.example.com/dir/ The object "dir/index.html", assuming no zero-byte object exists for /dir/ 200
A zero byte empty object, if it exists for /dir/. See the Troubleshooting topic for removing this zero byte object. 301

Two-object bucket

Suppose a bucket named www.example.com has been configured as a website with the following settings and files:

  • MainPageSuffix = "main.html"
  • NotFoundPage = "404.html"
  • The bucket contains two publicly shared objects: "main.html" and "404.html".

The following table shows the content served for selected URLs:

URL Requested Content Served HTTP response code
http://www.example.com
http://www.example.com/
The object "main.html". 200
http://www.example.com/index.html The object "404.html". 404

If an object is shared publicly, you can also view that object with the URL:

http://storage.googleapis.com/[BUCKET_NAME]/[OBJECT_NAME]

For example, the URL for an index.html object would be:

http://storage.googleapis.com/www.example.com/index.html

For more information about working with publicly accessible data, see Accessing Public Data.

Troubleshooting a bucket configured as a website

The following are some common issues that may be encoutered when setting up a bucket to host a static website, along with the resolution to those issues.

You want your content served through HTTPS

While you can serve your content through HTTPS using direct URI's such as https://storage.googleapis.com/my-bucket/my-object, when hosting a static website using a CNAME redirect, Cloud Storage only supports HTTP. To serve your content through a custom domain over SSL, set up a load balancer, use a third-party Content Delivery Network with Cloud Storage, or serve your static website content from Firebase Hosting instead of Google Cloud Storage.

Buckets are created before verifying a domain

If you try to create a bucket for a newly created domain before it is verified, you'll receive a warning message. In this case, you should choose the verification process that doesn't involve adding a meta tag to your home page or uploading an HTML file. Instead, verify ownership using the Domain name provider verification method with a DNS TXT or CNAME record, or else directly within Search Console. This verification can be done before the bucket is created.

Access is denied

If you get the following message for a web page served by your website:

<Error>
<Code>AccessDenied</Code>
<Message>Access denied.</Message>
</Error>

Check that the object is shared publicly. For an example of how to do this in Google Cloud Platform Console, see Sharing Data Publicly.

If you uploaded an object (for example, index.html), marked it as shared publicly, and then upload a new version of it, then you must reshare the object publicly because that permission is overwritten with the new upload.

Users are prompted to download content

If you specify a MainPageSuffix as an object that does not have a web content type, then instead of serving the page, site visitors are prompted to download the content. To resolve this issue, update the content-type metadata entry to a suitable value (e.g., text/html). You can do this, for instance, by using the gsutil setmeta command.

Accessing a directory path returns an empty object and a 301 HTTP response code

If your browser downloads a zero byte object and you get a 301 HTTP response code when accessing a directory, such as http://www.example.com/dir/, your bucket most likely contains an empty object of that name. To check, use the gsutil CLI:

  1. Open the Cloud Storage browser in the Google Cloud Platform Console.
    Open the Cloud Storage browser

  2. Click the Activate Google Cloud Shell button at the top of the Google Cloud Platform Console. Activate Google Cloud Shell

  3. Run gsutil ls -R gs://www.example.com/dir/. If the output includes http://www.example.com/dir/, you have an empty object at that location.
  4. Remove the empty object: gsutil rm gs://www.example.com/dir/

You can now access http://www.example.com/dir/ and have it return that directory's index.html file instead of the empty object.

Tips for working with a bucket configured as a website

The following are some tips to keep in mind when using a bucket to host a static website.

Adding subdomains

Suppose you also want to serve content at test.example.com, from a different bucket than the one that serves content at www.example.com. To do so:

  1. Create a new bucket test.example.com. Because you already verified the domain example.com, you can create buckets to support subdomains without additional verification.

  2. Add a new CNAME record for the subdomain.

    NAME                  TYPE     DATA
    test                  CNAME    c.storage.googleapis.com.
    

The following example shows what the subdomain bucket looks like in the Google Cloud Platform Console.

Bucket website subdomain example.
Example of a bucket configured for a website subdomain.

Setting cache parameters

You can control how or if your website assets are cached by configuring the Cache-Control metadata. Generally, only set cache control metadata for objects that are accessible to all anonymous users, which is a requirement for any object served from a Cloud Storage bucket as part of a static website.

Google Cloud Storage applies a cache control setting of 3600 seconds to objects that are accessible to all anonymous users, unless you specify explicit cache control settings. See Viewing and Editing Metadata for instructions for setting object metadata, such as Cache-Control.

API behavior

Website configurations are only used to interpret requests directed to CNAME aliases of c.storage.googleapis.com. (that is, requests where the hostname is a custom domain). For example, only requests to www.example.com show the index page.

Thus, API behavior for requests to Cloud Storage domains, such as storage.googleapis.com/www.example.com, is preserved. For example, you can continue to list objects in the www.example.com bucket as you would for any other bucket. In the case of the www.example.com bucket, the object listing you receive includes 404.html and index.html.

Hosting static assets for a dynamic website

You can use Google Cloud Storage to host static assets for a dynamic website that is hosted, for example, in Google App Engine or in Google Compute Engine. Some benefits of hosting your static assets, like images or Javascript files, in a bucket include:

  • Cloud Storage behaves essentially like a Content Delivery Network (CDN) with no work on your part because publicly readable objects are, by default, cached in the Cloud Storage network.

  • Bandwidth charges for accessing content typically cost less with Google Cloud Storage.

  • The load on your web servers is lessened when serving the static content from Cloud Storage.

You can also control caching, such as disabling caching or setting cache lifetime, for your publicly readable static assets by using cache control request headers. For more information, see Setting cache parameters.

When hosting static assets for a dynamic website, you do not need to create a CNAME record and point to a bucket with the same name as you do for a static website. For example, you could have a bucket named www_example_com_assets with appropriate assets configured as shared publicly and then access those assets using the Cloud Storage domain. For example, suppose you have the JavaScript file library.js in the bucket www_example_com_assets that is shared publicly, then you can access it as http://storage.googleapis.com/www_example_com_assets/library.js.

Bucket serving static assets.
Example of a bucket serving static assets.

Monitor your storage charges

If you are serving assets, either as a bucket configured as a static website, or serving static assets from a bucket for a dynamic website hosted outside of Google Cloud Storage, you should monitor the charges to your project that contains the bucket. Serving content incurs storage costs for hosting the content (per GB per Month), network egress (per GB), and retrieval operations (Class B). See the Google Cloud Storage pricing page for more details.

The simple pricing example on the pricing page can be used as an approximation for the use case of a low-traffic, static website. You can use the Pricing Calculator to generate a cost estimate based on your projected usage.

New Cloud Platform users might be eligible for a free trial.

If you are a current Cloud Platform user, you can get a detailed breakdown of your project costs on the billing page.

Monitor your resources on the go

Get the Google Cloud Console app to help you manage your projects.

Send feedback about...

Cloud Storage Documentation