# Shopify Admin Traffic By Page Report

> Report sessions, conversion rate, and bounce rate for every product and collection page using Shopify's analytics API — surfaces which pages earn eyeballs and which convert them.

- **Type:** Skill
- **Install:** `agentstack add skill-40rty-ai-shopify-admin-skills-shopify-admin-traffic-by-page-report`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [40RTY-ai](https://agentstack.voostack.com/s/40rty-ai)
- **Installs:** 0
- **Category:** [Data & Analytics](https://agentstack.voostack.com/c/data-and-analytics)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [40RTY-ai](https://github.com/40RTY-ai)
- **Source:** https://github.com/40RTY-ai/shopify-admin-skills/tree/main/skills/conversion-optimization/shopify-admin-traffic-by-page-report
- **Website:** http://skills.40rty.ai

## Install

```sh
agentstack add skill-40rty-ai-shopify-admin-skills-shopify-admin-traffic-by-page-report
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

## Purpose
Queries Shopify's built-in analytics engine (ShopifyQL) to surface session-level traffic data scoped to product and collection pages. Shows which pages are attracting the most traffic, how many sessions convert to orders, and where visitors are bouncing — ready input for SEO prioritisation, merchandising focus, and A/B test targeting. Read-only — no mutations are executed.

## Prerequisites
- Authenticated Shopify CLI session: `shopify auth login --store `
- API scopes: `read_reports`
- Shopify plan: ShopifyQL analytics is available on Basic and above; availability of `sessions` as a data source requires Shopify plan or higher

## Parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| store | string | yes | — | Store domain (e.g., mystore.myshopify.com) |
| format | string | no | human | Output format: `human` or `json` |
| dry_run | bool | no | false | Preview operations without executing mutations |
| days_back | integer | no | 30 | Lookback window in days (e.g., `30` = last 30 days) |
| page_type | string | no | both | Filter to: `products`, `collections`, or `both` |
| top_n | integer | no | 25 | Number of pages to show in the ranked output |
| sort_by | string | no | sessions | Ranking metric: `sessions`, `conversion_rate`, or `bounce_rate` |

## Workflow Steps

1. **OPERATION:** `shopifyqlQuery` — query (all landing pages)
   **Inputs:** ShopifyQL string `FROM sessions SHOW sessions, conversion_rate GROUP BY landing_page_path SINCE -d UNTIL today ORDER BY sessions DESC LIMIT 250`; `sessions` and `conversion_rate` are the confirmed available metrics for this data source
   **Expected output:** All landing pages with session counts and conversion rates; paginate via `OFFSET` if result count equals 250

2. **In-memory filtering:** Filter rows where `landing_page_path` starts with `/products/` (product pages) or `/collections/` (collection pages); apply `page_type` parameter; sort by `sort_by`; truncate to `top_n`; flag pages with sessions above median and `conversion_rate  **Note:** ShopifyQL does not support `LIKE`, `WHERE` string prefix filters, or aggregate aliases that shadow reserved column names (`sessions`, `conversion_rate`). All page-type filtering must be done in-memory after fetching all rows.

## GraphQL Operations

```graphql
# shopifyqlQuery:query (page traffic) — validated against api_version 2025-01
query TrafficByPage($query: String!) {
  shopifyqlQuery(query: $query) {
    parseErrors
    tableData {
      columns {
        name
        dataType
        displayName
      }
      rows
    }
  }
}
```

The `$query` variable (single call — all landing pages, filtered in-memory):
```
FROM sessions
SHOW sessions, conversion_rate
GROUP BY landing_page_path
SINCE -d
UNTIL today
ORDER BY sessions DESC
LIMIT 250
```

Then filter rows in-memory:
- Product pages: `landing_page_path.startsWith('/products/')`
- Collection pages: `landing_page_path.startsWith('/collections/')`
- `conversion_rate` is returned as a decimal (e.g. `0.016` = 1.6%) — multiply by 100 for display

> **Confirmed live against 2025-01:** `sessions` (INTEGER) and `conversion_rate` (PERCENT) are the available metrics. `WHERE … LIKE`, `bounce_rate`, `converted_sessions`, and aggregate aliases that shadow reserved names are not supported in ShopifyQL `FROM sessions`.

## Session Tracking

**Claude MUST emit the following output at each stage. This is mandatory.**

**On start**, emit:
```
╔══════════════════════════════════════════════╗
║  SKILL: traffic-by-page-report               ║
║  Store:                        ║
║  Started:              ║
╚══════════════════════════════════════════════╝
```

**After each step**, emit:
```
[N/TOTAL]   
          → Params: 
          → Result: 
```

**On completion**, emit:

For `format: human` (default):
```
══════════════════════════════════════════════
OUTCOME SUMMARY
  Lookback window:       days
  Page type:            
  Pages analysed:       
  Top session page:      ( sessions)
  Top converting page:   (%)
  Errors:               0
  Output:               traffic_by_page_.csv
══════════════════════════════════════════════
```

For `format: json`, emit:
```json
{
  "skill": "traffic-by-page-report",
  "store": "",
  "started_at": "",
  "completed_at": "",
  "dry_run": false,
  "steps": [
    { "step": 1, "operation": "ProductPageTraffic", "type": "query", "params_summary": "products, last  days", "result_summary": " product pages returned", "skipped": false },
    { "step": 2, "operation": "ProductPageTraffic", "type": "query", "params_summary": "collections, last  days", "result_summary": " collection pages returned", "skipped": false }
  ],
  "outcome": {
    "days_back": 30,
    "page_type": "both",
    "pages_analysed": 0,
    "results": [],
    "errors": 0,
    "output_file": "traffic_by_page_.csv"
  }
}
```

## Output Format
CSV file `traffic_by_page_.csv` with one row per page:

| Column | Description |
|--------|-------------|
| `page_type` | `product` or `collection` |
| `page_path` | URL path (e.g., `/products/red-sneaker`) |
| `sessions` | Total sessions landing on this page |
| `conversion_rate_pct` | Conversion rate as a percentage (API returns decimal; multiplied by 100) |
| `optimisation_flag` | `high_traffic_low_conversion` if sessions > median and conversion_rate < 2% |

For `format: human`, a ranked table is printed inline truncated to `top_n`, followed by a short list of optimisation candidates flagged with `high_traffic_low_conversion`.

## Error Handling
| Error | Cause | Recovery |
|-------|-------|----------|
| `parseErrors` non-empty | Invalid ShopifyQL syntax — each error is a plain string | Log each string, surface to user; common causes: aliasing a reserved column name (`sessions`, `conversion_rate`), using `LIKE`, or referencing a non-existent column like `converted_sessions` or `bounce_rate` |
| `tableData` is null | No analytics data for the period | Extend `days_back`; confirm the store has traffic |
| `ACCESS_DENIED` / `read_reports` scope missing | Scope not granted at auth time | Re-authenticate adding `read_reports` scope |
| `THROTTLED` | Analytics query rate limit | Wait 2 s, retry up to 3 times |
| No product/collection rows after filtering | Dev/test store or no direct landing traffic to catalog pages | Widen `days_back`; note that most traffic may enter via homepage |

## Best Practices
1. A `conversion_rate_pct` below 1% on a high-traffic product page is worth investigating — check whether the product is out of stock, has poor images, or lacks a clear call-to-action.
2. Collection pages with high bounce rates often signal a poor match between the ad or search term that drove the session and the collection content — review the collection SEO title.
3. Use `page_type: products` after a new product launch to track early traction without noise from collection traffic.
4. Combine with `top-product-performance` to correlate high-converting pages with the products generating the most actual revenue.
5. Re-run the report weekly after making on-page changes (copy, imagery, pricing) to measure the impact — the 7-day window (`days_back: 7`) isolates post-change behaviour cleanly.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [40RTY-ai](https://github.com/40RTY-ai)
- **Source:** [40RTY-ai/shopify-admin-skills](https://github.com/40RTY-ai/shopify-admin-skills)
- **License:** MIT
- **Homepage:** http://skills.40rty.ai

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-40rty-ai-shopify-admin-skills-shopify-admin-traffic-by-page-report
- Seller: https://agentstack.voostack.com/s/40rty-ai
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
