OG Image on Google Cloud Storage: Host Social Preview Images with GCS

How to host og:image files on Google Cloud Storage — covering public access setup, HTTPS URLs, CORS configuration, and serving via Cloud CDN for fast social previews.

Updated March 2026

Why GCS for OG Images?

Google Cloud Storage (GCS) is a solid choice for hosting static OG images: global CDN distribution, simple public access configuration, and HTTPS by default for all storage.googleapis.com URLs. GCS URLs are always HTTPS — unlike AWS S3 direct URLs — which means no CloudFront equivalent is strictly required.

Step 1: Create a Public Bucket

# Create a bucket (choose your region)
gsutil mb -l us-central1 gs://your-bucket-name

# Make the bucket publicly readable
gsutil iam ch allUsers:objectViewer gs://your-bucket-name

# Or via gcloud CLI (recommended for new projects):
gcloud storage buckets create gs://your-bucket-name   --location=us-central1   --uniform-bucket-level-access

gcloud storage buckets add-iam-policy-binding gs://your-bucket-name   --member=allUsers   --role=roles/storage.objectViewer

Note: GCS now encourages Uniform bucket-level access (as above) over per-object ACLs. With uniform access + allUsers objectViewer, all objects in the bucket are publicly readable.

Step 2: Upload Your OG Images

# Upload a single OG image with correct Content-Type
gsutil -h "Content-Type:image/png"        -h "Cache-Control:public, max-age=31536000"        cp og-image.png gs://your-bucket-name/og/page-slug.png

# Upload multiple images
gsutil -m -h "Content-Type:image/png"        -h "Cache-Control:public, max-age=31536000"        cp og/*.png gs://your-bucket-name/og/

# Using gcloud CLI
gcloud storage cp og-image.png gs://your-bucket-name/og/page-slug.png   --cache-control="public, max-age=31536000"

Step 3: Use the Public URL in Your og:image Tag

GCS public URLs follow this format — and they're always HTTPS:

<!-- Direct GCS URL (HTTPS by default) -->
<meta property="og:image" content="https://storage.googleapis.com/your-bucket-name/og/page-slug.png" />
<meta property="og:image:width"  content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:image:type"   content="image/png" />

CORS Configuration (If Needed)

Most social crawlers don't need CORS. But if you're loading OG images from JavaScript (e.g., canvas-based tools), configure CORS on the bucket:

# cors-config.json
[
  {
    "origin": ["*"],
    "method": ["GET", "HEAD"],
    "responseHeader": ["Content-Type"],
    "maxAgeSeconds": 3600
  }
]

# Apply CORS config
gsutil cors set cors-config.json gs://your-bucket-name

Custom Domain with Cloud CDN

For a branded URL like cdn.yoursite.com/og/..., use a Cloud CDN backend pointing to your GCS bucket:

# 1. Create a backend bucket
gcloud compute backend-buckets create og-images-backend   --gcs-bucket-name=your-bucket-name   --enable-cdn

# 2. Create a URL map
gcloud compute url-maps create og-images-lb   --default-backend-bucket=og-images-backend

# 3. Create HTTPS proxy (requires SSL cert)
gcloud compute target-https-proxies create og-https-proxy   --url-map=og-images-lb   --ssl-certificates=your-ssl-cert

# 4. Create forwarding rule
gcloud compute forwarding-rules create og-https-rule   --target-https-proxy=og-https-proxy   --ports=443   --global

Point your DNS cdn.yoursite.com to the forwarding rule IP, then use:

<meta property="og:image" content="https://cdn.yoursite.com/og/page-slug.png" />

Uploading from Node.js

import { Storage } from "@google-cloud/storage";

const storage = new Storage({
  projectId: process.env.GCP_PROJECT_ID,
  credentials: JSON.parse(process.env.GCP_SERVICE_ACCOUNT_KEY!),
});

const bucket = storage.bucket("your-bucket-name");

export async function uploadOgImage(
  slug: string,
  pngBuffer: Buffer
): Promise<string> {
  const file = bucket.file(`og/${slug}.png`);
  
  await file.save(pngBuffer, {
    contentType: "image/png",
    metadata: {
      cacheControl: "public, max-age=31536000, immutable",
    },
  });
  
  // GCS direct URL (always HTTPS)
  return `https://storage.googleapis.com/your-bucket-name/og/${slug}.png`;
}

Verify your GCS-hosted OG image →

Paste your URL into OGFixer to confirm the image loads and renders correctly across Twitter, LinkedIn, Discord, and Slack.

Preview my OG image →