Skip to content

On a schedule

Weekly GA4 top pages report in Google Sheets

Every Monday a new tab lists last week's top 50 pages by views, with users, engagement time and change against the week before.

Runs
On a schedule
Apps
Google Analytics, Google Sheets
AI
Not needed
Access
analytics.readonly; Google Sheets read+write

Send this to your assistant

Create a ClickRuntime automation: every Monday at 7am, add a new tab to my GA4 sheet named after last week with the top 50 pages by views, their users, average engagement time and percentage change in views from the week before.

Paste it into your assistant. It tells you what it will send or change before it runs live.

First time? Adding ClickRuntime to your assistant takes about two minutes.

Why use it

Why teams use this automation

Content teams want to know every week which pages are pulling their weight and which are slipping. In GA4 that means building an exploration, picking dates and comparing two periods by eye.

This automation adds a tab every Monday with the top 50 pages by views, their users and engagement time, and how each moved compared with the week before.

Content marketers, SEO leads and site owners use it as the agenda for their weekly content review.

What you get out of it

  • Winners and losers at a glance

    The change column shows which pages grew or dropped against last week.

  • New pages spotted

    Freshly published pages are marked new, so launches are easy to track.

  • Engagement next to views

    A page with many views but little time spent may need better content or a clearer call to action.

  • Weekly archive

    Each week keeps its own tab, so you can look back at any week.

  • No GA4 explorations to maintain

    The report is built from the Data API, not from saved views that break.

How it works

What happens, step by step

  1. Every Monday ClickRuntime runs two GA4 reports by page: last week and the week before.

  2. It picks the 50 pages with the most views last week and works out the change from the previous week.

  3. A new tab named after the week, such as Week of 2026-11-02, is added with the table.

Before it runs live

  • Connect Google Analytics
  • Connect your Google Sheets account and pick the spreadsheets it may use

What you get

RunsOn a schedule
Weekly GA4 top pages report in Google Sheetstoday, 9:00Succeeded
Google Sheets · GA4 pages › Week of 2026-11-02/pricing | 3,412 views | 2,190 users | 0:58 engaged | +18% /blog/sheets-automation | 2,076 views | 1,804 users | 2:41 engaged | new

Build your own

Need it to work differently?

This template is a starting point. Copy the prompt and change it, or describe a different automation from scratch, with your own conditions, more apps or an AI step. Your assistant writes it, tests it and runs it on ClickRuntime.
  • Your own rules

    Conditions, thresholds, filters and exceptions, written the way you'd explain them to a colleague.

  • Any number of apps

    One automation can read from one app and update several others. Over 248 apps are ready, and anything with an API works too.

  • AI where it helps

    Summaries, classification, extraction and drafts use ClickRuntime's built-in AI, with no extra key.

  • On a schedule or on each event

    Runs as often as every 5 minutes, or the moment an app sends an event, and keeps track of what it already handled.

Changes you can ask for

  • Run it at a different time, more or less often, or only on weekdays
  • Add an AI step, for example to summarize, sort or draft a reply
  • Add another app, for example also send it to Slack
  • Combine it with other Google Analytics and Google Sheets steps into one automation

Under the hood

The code that runs this automation

This is the Python script that runs each time the automation starts. Your AI assistant writes it for you when you send the prompt, and you allow each step in your assistant. To change how the automation works, describe the change to your assistant and it updates the script for you. For every function it can use, see the script reference.
weekly_ga4_top_pages_report_in_google_sheets.pyexample
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from datetime import date, timedelta
from clickruntime import on_trigger, credentials, http

PROPERTY = "123456789"
SHEET_ID = "your-spreadsheet-id"

def ga(body):
    r = http.post(f"https://analyticsdata.googleapis.com/v1beta/properties/{PROPERTY}:runReport", json=body,
                  headers={"Authorization": f"Bearer {credentials.connection('google', 'work')}"})
    r.raise_for_status()
    return r.json().get("rows", [])

def pages(start, end, limit):
    rows = ga({"dateRanges": [{"startDate": str(start), "endDate": str(end)}], "dimensions": [{"name": "pagePath"}],
               "metrics": [{"name": "screenPageViews"}, {"name": "totalUsers"}, {"name": "userEngagementDuration"}],
               "orderBys": [{"metric": {"metricName": "screenPageViews"}, "desc": True}], "limit": limit})
    return {r["dimensionValues"][0]["value"]: [float(v["value"]) for v in r["metricValues"]] for r in rows}

@on_trigger
def run(event):
    monday = date.today() - timedelta(days=date.today().weekday() + 7)
    this, prev = pages(monday, monday + timedelta(days=6), 50), pages(monday - timedelta(days=7), monday - timedelta(days=1), 1000)
    table = [["Page", "Views", "Users", "Avg engagement (s)", "Change in views"]]
    for path, (views, users, secs) in this.items():
        before = prev.get(path, [0])[0]
        change = f"{(views - before) / before:+.0%}" if before else "new"
        table.append([path, int(views), int(users), round(secs / max(users, 1)), change])
    name = f"Week of {monday}"
    book = build("sheets", "v4", credentials=Credentials(credentials.connection("google", "work")), cache_discovery=False).spreadsheets()
    book.batchUpdate(spreadsheetId=SHEET_ID, body={"requests": [{"addSheet": {"properties": {"title": name, "index": 0}}}]}).execute()
    book.values().update(spreadsheetId=SHEET_ID, range=f"'{name}'!A1", valueInputOption="RAW", body={"values": table}).execute()
    return {"tab": name, "pages": len(table) - 1}

FAQ

Common questions

Why a new tab each week instead of one long table?
A tab per week is easy to read in a meeting and keeps last week's list intact. If you prefer one long table for charts, ask your assistant to append rows with a week column instead.
How is engagement time worked out?
It is total engagement time for the page divided by its users, so it shows how long a typical visitor spent actively on the page.
What does "new" mean in the change column?
The page had no views in the week before, usually because it was just published or renamed.
What permissions does it need?
analytics.readonly; Google Sheets read+write. Nothing else in your accounts is used.
Does it need AI?
No. It runs without AI, so it doesn't use your plan's AI allowance.
How many runs does it use?
One run each time it runs (on a schedule). Checks that find nothing to do and stop right away aren't counted.
Can I change how it works?
Yes. Describe the change to your AI assistant, for example a different schedule, channel or filter. It updates the automation, tests it and tells you what changed.

Set up “Weekly GA4 top pages report in Google Sheets” from your assistant

Copy the prompt above, or connect your assistant first. Free plan, no credit card.