# Read a Google Sheet in React

The obvious approach — call the Google Sheets API from your component — is the one you must not take. Here is why, and what to do instead.

*Last updated: 2026-07-13 · Source: <https://pastesheet.com/guides/read-google-sheet-in-react>*

## Key facts

- Never call Google's Sheets API from the browser. **Anything shipped to the client is public** — an API key in front-end code is visible in dev tools, and a leaked key is someone else's quota to burn. ([source](https://developers.google.com/workspace/sheets/api/guides/authorizing))
- The Google Sheets API allows **300 read requests per minute per project** and **60 per minute per user**. Past that it returns `429 RESOURCE_EXHAUSTED`. ([source](https://developers.google.com/workspace/sheets/api/limits))
- PasteSheet's MCP server exposes three tools — `list_tabs`, `get_schema` and `query_rows` — and is **read-only by design**: an agent can query your sheet but can never modify it.
- That is what makes a client-side fetch safe here: the endpoint has **no write path and no Google credential behind it**. For non-public data, call a private endpoint from your server with a bearer key instead.

## How do you read a Google Sheet in React?

Fetch it from an endpoint that serves the sheet as JSON. What you must **not** do is call Google's API directly from the browser with a key — anything shipped to the client is public, and a leaked API key is someone else's quota to burn.

That is the trap this question usually walks into. The fix is to keep the credential out of the browser entirely: put a public, read-only endpoint in front of the sheet and let the client fetch that.

## Fetching in a component

Nothing exotic — it is a normal JSON fetch, and the values come back typed:

```tsx
import { useEffect, useState } from 'react'

export function Listings() {
  const [rows, setRows] = useState([])

  useEffect(() => {
    fetch('https://pastesheet.com/api/your-endpoint-id?status=active&limit=50')
      .then((r) => r.json())
      .then((res) => setRows(res.data))
  }, [])

  return (
    <ul>
      {rows.map((row) => (
        <li key={row.id}>{row.name} — {row.price}</li>
      ))}
    </ul>
  )
}
```

## Public data only

A client-side fetch means the endpoint is reachable by anyone who opens dev tools. That is fine for a public catalog, a directory, or an FAQ — which is what most sheet-backed React apps are showing anyway.

If the data is not public, do not fetch it from the browser. Call a [private endpoint](https://pastesheet.com/features) from your server (a Next.js route handler, an API route) with a bearer key, and pass the rows down as props.

## What it costs

**MCP is included on the Free plan.** Connect any **public** endpoint over MCP with no Google Cloud project and no credit card. Private endpoints and the account-wide workspace server need a paid plan (from **Starter ($9/mo)**) for the keys and OAuth they authenticate with.

Pro adds full-text search and aggregation (`count`, `sum`, `avg`, `group_by`) that your AI agent can call through `query_rows`.

**Free — $0/month.** For side projects and trying things out.

- Endpoints: 3
- Requests: 2,000 / month
- Rows per endpoint: 500
- Tabs per endpoint: 1
- Rate limit: 60 / minute

## Frequently asked questions

### Can I call the Google Sheets API from React?

You can, and you should not. Any API key in front-end code is visible to anyone who opens dev tools. Fetch from a public read-only endpoint instead, or call a private one from your server.

### Will readers be able to change my sheet through the API?

No. PasteSheet is read-only by design — there is no write path — so a public endpoint is safe to call from client-side code.

### How do I keep the data fresh?

The endpoint is cached, with a TTL you set from 30 seconds to an hour. Edits to the sheet appear once that window elapses; there is nothing to redeploy.

### What about Next.js?

Fetch server-side in a route handler or server component, which also lets you use a private endpoint with a bearer key safely, since the key never reaches the browser.

## Sources

- [Authorize requests — Google Sheets API](https://developers.google.com/workspace/sheets/api/guides/authorizing) — Google
- [Usage limits — Google Sheets API](https://developers.google.com/workspace/sheets/api/limits) — Google

## Related guides

- [How to Read a Google Sheet in Laravel](https://pastesheet.com/guides/read-google-sheet-in-laravel) — Pull Google Sheet rows into Laravel as typed JSON with Http::get and a cache. No Google client library, no service account JSON, no Cloud project.
- [How to Read a Google Sheet in Python](https://pastesheet.com/guides/read-google-sheet-in-python) — Three ways to read a Google Sheet from Python: gspread, the official API, and a plain HTTP endpoint. Working code and the gotchas for each approach.
- [Google Sheets Database for a Website](https://pastesheet.com/guides/google-sheets-database-for-website) — Use Google Sheets as a database for your website: serve content, listings, and copy as JSON your pages fetch. Editable by your team, cached, and code-free.
- [Turn Google Sheets Into a REST API (No Code)](https://pastesheet.com/guides/google-sheets-rest-api) — Turn a public or restricted Google Sheet into a live JSON REST API with filtering, sorting, and pagination — no backend, no code.

---

[PasteSheet](https://pastesheet.com) turns any Google Sheet into a live REST API and MCP server for AI agents — no backend, no code. Canonical HTML version of this page: <https://pastesheet.com/guides/read-google-sheet-in-react>
