ScreenshotNeo

BlogHow-to

How to Publish Google Sheets Data on a Website

Publish a Google Sheet as a live, read-only webpage or embed one tab, range, chart, or custom view with the right access and refresh settings.

By the ScreenshotNeo team1 October 20268 min read

Fastest answer: In Google Sheets, choose File → Share → Publish to web, select the whole spreadsheet or one tab, choose a format, and click Publish. Copy the public URL for a link, or choose Embed and paste the generated iframe into your website. The published view is read-only and updates after source edits, usually with a short delay.

Google’s official instructions are in Publish a file to the web. Before publishing, remove private columns and confirm the audience setting: publishing can expose the selected data to everyone on the web, everyone in an organisation, or a selected group.

Choose the right publishing method

Method Best for Access Presentation control Refresh behavior
Publish to web link A downloadable or view-only public page Public or organisation audience Low Automatic, sometimes delayed
Publish to web iframe Showing a sheet inside a blog or site Public or organisation audience Low to medium Automatic, sometimes delayed
Visualization API Interactive charts and custom tables Public or link-shared sheet; private data needs credentials High You control refresh logic
Sheets API v4 Authenticated reads, writes, transformations, and app backends OAuth or service-account design Highest You control caching and refresh
Apps Script web app A custom browser interface backed by a sheet Script deployment audience High You control server code

Publish a Google Sheet as a public webpage

  1. Open the spreadsheet and remove or separate confidential data.
  2. Choose File → Share → Publish to web.
  3. In the first menu, select Entire document or a specific sheet tab.
  4. Choose Web page for a browser page, or another offered format when you need a data export.
  5. Click Publish and confirm.
  6. Copy the generated URL. Test it in a private browser window before adding it to your site.

Publishing creates a read-only representation. Visitors can see values, charts, and cell formatting, but they cannot inspect or edit the original formulas through the published view.

Show only one tab

Select the individual sheet instead of Entire document before publishing. This is useful for a public “Summary” tab while keeping working tabs out of the published scope. Treat the selected scope as a visibility decision, not as a security boundary: anything in the published scope is exposed to its audience.

Embed the published sheet in HTML

After publishing, select Embed in the dialog and copy Google’s iframe code. A minimal responsive container looks like this:

<div class="sheet-frame">
  <iframe
    src="PASTE_THE_PUBLISHED_EMBED_URL_HERE"
    title="Public spreadsheet"
    loading="lazy"
    referrerpolicy="no-referrer-when-downgrade">
  </iframe>
</div>

<style>
  .sheet-frame {
    width: 100%;
    overflow: hidden;
  }
  .sheet-frame iframe {
    width: 100%;
    min-height: 620px;
    border: 0;
  }
</style>

Use the exact URL from the Publish to web dialog. Do not replace it with the private edit URL from your browser address bar. Your site’s Content Security Policy may need to allow the Google publishing host in frame-src.

Control the embedded view with URL parameters

Google documents several display parameters for published spreadsheets. Add them to the published URL with &:

Parameter Example Effect
gid gid=123456789 Selects a sheet tab by its tab ID.
range range=A1:B14 Limits the displayed rows and columns.
widget widget=false Controls whether the sheet tab bar appears.
headers headers=false Controls row and column headers.
chrome chrome=false Controls title and footer chrome.
<iframe
  src="https://docs.google.com/spreadsheets/d/e/PUBLISHED_ID/pubhtml?gid=123456789&range=A1:B14&widget=false&headers=false&chrome=false"
  title="Quarterly metrics">
</iframe>

These parameters change presentation. They do not protect cells or hide data from someone who can access the published spreadsheet. Publish only the rows and columns you are comfortable exposing.

Keep the website view updated

Edit the source spreadsheet normally. Google says edits are reflected in the published version automatically, but the change can take a few minutes to appear. Avoid promising visitors a second-by-second feed unless you build a custom integration.

  • Put public output in a dedicated tab so internal notes are never in the published scope.
  • Use a visible “Last updated” cell populated by your workflow.
  • Test the published URL after structural changes such as renaming a tab or changing its range.
  • If your site caches iframe HTML, reduce that cache duration or purge it after important updates.

Publish a chart or custom table with the Visualization API

For interactive charts, Google’s Visualization API spreadsheet data source can read a public or link-shared spreadsheet. Private spreadsheets require an end-user credential and authorization flow.

<div id="chart" style="height:360px"></div>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script>
  google.charts.load('current', { packages: ['corechart'] });
  google.charts.setOnLoadCallback(drawChart);

  function drawChart() {
    const query = new google.visualization.Query(
      'https://docs.google.com/spreadsheets/d/SPREADSHEET_ID/gviz/tq?sheet=Summary&range=A1:B20'
    );
    query.send(response => {
      if (response.isError()) {
        document.getElementById('chart').textContent = response.getMessage();
        return;
      }
      const chart = new google.visualization.LineChart(document.getElementById('chart'));
      chart.draw(response.getDataTable(), { legend: { position: 'bottom' } });
    });
  }
</script>

Use the Sheets API for authenticated or write-enabled applications

The Google Sheets API v4 exposes methods including spreadsheets.get, spreadsheets.create, and spreadsheets.batchUpdate. Use it when your application must keep data private, transform rows, accept edits, or apply its own caching and authorization.

cURL: read a public range

curl "https://sheets.googleapis.com/v4/spreadsheets/SPREADSHEET_ID/values/Summary!A1:B20?key=YOUR_API_KEY"

This pattern is suitable only for data your project intentionally makes readable with that API key and spreadsheet sharing configuration. Do not put OAuth refresh tokens or service-account keys in browser JavaScript.

Python: read values with an OAuth credential

from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build

SCOPES = ["https://www.googleapis.com/auth/spreadsheets.readonly"]
creds = Credentials.from_authorized_user_file("token.json", SCOPES)
service = build("sheets", "v4", credentials=creds)
result = service.spreadsheets().values().get(
    spreadsheetId="SPREADSHEET_ID",
    range="Summary!A1:B20",
).execute()
print(result.get("values", []))

Node.js: read values with an OAuth credential

import { google } from 'googleapis';

const auth = new google.auth.GoogleAuth({
  keyFile: 'service-account.json',
  scopes: ['https://www.googleapis.com/auth/spreadsheets.readonly'],
});
const sheets = google.sheets({ version: 'v4', auth });
const { data } = await sheets.spreadsheets.values.get({
  spreadsheetId: 'SPREADSHEET_ID',
  range: 'Summary!A1:B20',
});
console.log(data.values ?? []);

Build a custom page with Apps Script

Apps Script can publish a script as a web app accessible from a browser. This gives you server-side control over which rows are returned and how they are rendered. Follow Google’s web app deployment guide, then choose the deployment audience that matches your data.

function doGet() {
  const sheet = SpreadsheetApp.openById('SPREADSHEET_ID').getSheetByName('Summary');
  const values = sheet.getRange('A1:B20').getDisplayValues();
  const rows = values.map(row => '<tr>' + row.map(cell => '<td>' + escapeHtml(cell) + '</td>').join('') + '</tr>').join('');
  return HtmlService.createHtmlOutput('<table>' + rows + '</table>');
}

function escapeHtml(value) {
  return String(value).replace(/[&<>"']/g, char => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[char]));
}

Or skip the browser setup

If the goal is a clean image or PDF of the published sheet on a page, ScreenshotNeo can capture the URL with one request. Its consent step accepts cookie banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be disabled. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing result.

See the ScreenshotNeo documentation for all options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://docs.google.com/spreadsheets/d/e/PUBLISHED_ID/pubhtml -o sheet.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://docs.google.com/spreadsheets/d/e/PUBLISHED_ID/pubhtml"}, timeout=90)
open("sheet.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://docs.google.com/spreadsheets/d/e/PUBLISHED_ID/pubhtml' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo also provides an MCP server so Claude, Cursor, and other MCP clients can use take_screenshot, get_page_info, and capture_pdf. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.

Security and privacy checklist

  • Remove names, emails, credentials, internal notes, and hidden helper columns from the published scope.
  • Check whether the audience is the public web, your organisation, or a selected group.
  • Open the URL while signed out to verify what an ordinary visitor can see.
  • Remember that an iframe display range is not an access-control mechanism.
  • Stop publishing when the page is no longer needed: return to Published content & settings and choose Stop publishing.

Troubleshooting

Symptom Likely cause Fix
Visitors see an access error The file or published audience does not include them. Review sharing and Publish to web audience settings, then test signed out.
The wrong tab appears The URL has the wrong gid or the wrong tab was selected. Republish the intended tab and copy its generated URL; verify the gid.
Too many rows are visible The whole document was published or the range is too broad. Publish a dedicated tab or set a narrower range.
Changes are not visible yet Google’s published copy has not refreshed, or your site cached it. Wait a few minutes, reload in a private window, and purge your site’s cache.
Iframe is blocked Your Content Security Policy or a frame restriction blocks the Google host. Allow the published Google host in frame-src and check browser console errors.
Charts or formatting look different The published renderer is read-only and may not match the editing interface. Use the Visualization API or a custom application when exact presentation control matters.
Private data must stay private Publish to web is the wrong access model. Use the authenticated Sheets API or an Apps Script web app with restricted deployment.

Performance, reliability, and cost notes

  • Native embeds: require little code, but the rendered view and refresh timing are controlled by Google. Use lazy loading and a sensible iframe height.
  • API integrations: let you cache responses, select only needed ranges, retry transient failures, and render lightweight HTML. Respect API quotas and keep credentials server-side.
  • Large sheets: publish a summary tab or narrow range instead of a full operational workbook. This reduces page weight and limits accidental exposure.
  • Costs: Google Sheets publishing and APIs have account and quota policies that can change; check the current Google Cloud and Workspace terms for your project. ScreenshotNeo has 1,000 free shots monthly with no card, then plans from $5 for 3,000.

FAQ

Can visitors edit the embedded sheet?

No. Publish to web creates a read-only representation. Use an authenticated application or a controlled form when visitors must submit changes.

Can I publish just a range?

Yes. Use a dedicated published tab or the documented range display parameter such as A1:B14. Review the full publication scope for privacy.

Will formulas be exposed?

The published view shows values and formatting, not an editing interface for formulas. Still remove sensitive helper data before publishing.

How do I remove a published page?

Open Publish to web, return to Published content & settings, and choose Stop publishing.

Which method should I use for a private dashboard?

Use the Sheets API with OAuth or a restricted Apps Script web app. Public publishing is designed for data you are willing to expose to its configured audience.