Cross Street CoffeeDemo data

Data sources Which connections are live right now.Each source reports its own status, and any problem is written in plain English.

Live, demo or off. Until Shopify is connected every panel shows demo data, and live and demo are never mixed.

  • ShopifyDemoAdd SHOPIFY_STORE_DOMAIN, SHOPIFY_CLIENT_ID and SHOPIFY_CLIENT_SECRET to go live.
  • Sessions and funnelDemoDemo sessions until Shopify is connected.
  • Meta adsDemoDemo spend and creatives.
  • Google AdsDemoDemo spend and creatives.
  • TikTok adsOffNot in the demo. Add TIKTOK_APP_ID and TIKTOK_APP_SECRET in Vercel, then click Connect TikTok in Settings.
  • RechargeDemoDemo subscriber counts.
  • KlaviyoDemoDemo campaign sends and email revenue.
  • Ticket storageOffIn memory only, so tickets reset on each deploy. Connect a Redis store to the Vercel project to keep them.
  • PasswordOffNo DASHBOARD_PASSWORD set. Fine for the demo, required before live data.

Connect this demo brand's Shopify

A read-only app in the Shopify Dev Dashboard, inside the organisation that owns this demo brand's store. About fifteen minutes.

  1. In dev.shopify.com, use the organisation switcher to pick the organisation that owns this demo brand's store, not another brand's. If it isn't listed, ask the store owner to invite you to it.
  2. Open the Cross Street Coffee Dashboard app, or click Create app and call it that (app names can be 30 characters at most). Go to Versions, then Create version.
  3. Set App URL to https://www.thatotheragency.co.uk and untick Embed app in Shopify admin.
  4. Set Scopes to read_reports,read_orders,read_customers,read_products, leave Optional scopes empty, and click Release.
  5. Open the app's Home, scroll down, click Install app, choose this demo brand's store and click Install.
  6. Open Settings in the app and copy the Client ID and Client secret.
  7. In Vercel, open the dashboard-demo project, then Settings, Environment Variables. Add SHOPIFY_STORE_DOMAIN, SHOPIFY_CLIENT_ID, SHOPIFY_CLIENT_SECRET and DASHBOARD_PASSWORD for Production, then redeploy.

If the status above says shop_not_permitted, the app and the store are in different organisations in the Dev Dashboard. If a scope is missing, add it to a new version, release it, and click Install app again.

Connect Meta ads

A read-only system user token for this demo brand's ad account. About ten minutes.

  1. In developers.facebook.com, create a Business app called Cross Street Coffee Dashboard with the Marketing API use case, and connect it to this demo brand's business portfolio. It can stay unpublished.
  2. In Meta Business settings for Cross Street Coffee, open Users, then System users, and add a system user with the Employee role. Give it a different name from the app, for example Cross Street Coffee Reporting, or Meta won't save it.
  3. Click Assign assets: give it the Cross Street Coffee ad account with view performance access only, and the Cross Street Coffee Dashboard app. The ads_read permission only appears once the app is assigned.
  4. Click Generate new token, pick the Cross Street Coffee Dashboard app, set expiry to Never, tick only ads_read, and copy the token. Meta only shows it once.
  5. In Vercel add META_ACCESS_TOKEN and META_AD_ACCOUNT_ID (the number from Ads Manager's account menu) for Production, then redeploy.

Connect Google Ads

A read-only service account, so there's no sign-in to expire. About fifteen minutes. No manager account or developer token needed since September 2026.

  1. In console.cloud.google.com, create a project called Cross Street Coffee Dashboard, then under APIs & Services, Library, enable the Google Ads API. Use a new project rather than another brand's, so either brand's access can be removed on its own.
  2. On the Google Ads API Overview page, expand Apply for next access level and apply for Explorer access. Google usually approves it automatically.
  3. Under IAM & Admin, Service accounts, create one called dashboard-demo. On its Keys tab, add a key, create new key, JSON. Copy its email address.
  4. In this demo brand's Google Ads, go to Admin, Access and security, click +, paste the service account email and choose Read only.
  5. In Vercel add GOOGLE_ADS_SERVICE_ACCOUNT_JSON (the whole key file) and GOOGLE_ADS_CUSTOMER_ID for Production, redeploy, and delete the downloaded key file.

Google spend, conversions and conversion value count towards MER, CAC and ROAS. Ads named with script and hook tags (S07 H03) also appear in Creative performance.

Connect TikTok ads

Only needed if Cross Street Coffee runs TikTok ads. A developer app with read-only reporting; TikTok reviews the developer profile and the app, up to three business days each.

  1. At business-api.tiktok.com/portal, click Become a Developer. Use a company email whose domain matches the website you enter; personal email addresses are rejected.
  2. Once approved, go to My Apps, Create an App. Set the advertiser redirect URL to https://www.thatotheragency.co.uk/api/tiktok/callback and tick only Ad Account Management and Reporting.
  3. Once the app is approved, copy the App ID and Secret from its Basic Information page into Vercel as TIKTOK_APP_ID and TIKTOK_APP_SECRET, then redeploy.
  4. Click Connect TikTok below, tick this demo brand's ad account, and confirm with the code TikTok emails.
The Connect TikTok button appears once TIKTOK_APP_ID and TIKTOK_APP_SECRET are in Vercel.

Environment variables

Set these in Vercel. Nothing secret is stored in the repository.

VariablePurpose
SHOPIFY_STORE_DOMAINrequired for livethis demo brand's myshopify.com address (Shopify admin, Settings, Domains). Not northbank.example.com. another brand's stores are refused.
SHOPIFY_CLIENT_IDrequired for liveFrom the app's Settings page in the Dev Dashboard.
SHOPIFY_CLIENT_SECRETrequired for liveFrom the same page. Swapped for a 24 hour Admin API token automatically, so there's no token to copy or renew.
DASHBOARD_PASSWORDrequired for livePassword for the whole dashboard. Live data stays off until this is set.
REDIS_URLAdded automatically when you connect a Redis store to this Vercel project. Keeps tickets, feature counters and the report cache. Use a new store, not another brand's. Upstash REST credentials (KV_REST_API_URL and KV_REST_API_TOKEN) also work.
SHOPIFY_SALES_FILTEROptional ShopifyQL condition applied to every sales query, for example is_b2b_order IS NOT TRUE to keep wholesale out of the numbers.
BUNDLE_MATCHRegex for product titles that count as bundles. Defaults to the duos, kits, routines and collections. Shopify bundle line items always count.
GIFT_MATCHRegex for free gift lines, shown in grey in Units sold so they don't read as best sellers. Defaults to the gift app's "(100% off)" copies.
META_ACCESS_TOKEN / META_AD_ACCOUNT_IDSystem user token with only ads_read, plus this demo brand's ad account id. Spend, MER, CAC, ROAS and creative-level rows. another brand's ad account is refused. META_API_VERSION defaults to v25.0.
GOOGLE_ADS_SERVICE_ACCOUNT_JSONThe whole JSON key file of a Google Cloud service account added to this demo brand's Google Ads account as Read only. The Cloud project needs the Google Ads API enabled and Explorer access.
GOOGLE_ADS_CUSTOMER_IDthis demo brand's 10 digit Google Ads customer ID, dashes optional. another brand's account is refused. GOOGLE_ADS_LOGIN_CUSTOMER_ID is only needed if access goes through a manager account.
TIKTOK_APP_ID / TIKTOK_APP_SECRETOnly if Cross Street Coffee runs TikTok ads. From the TikTok developer app's Basic Information page, then click Connect TikTok above.
TIKTOK_ADVERTISER_IDOnly needed if the TikTok authorisation covers more than one ad account. another brand's ad accounts are always left out.
KLAVIYO_API_KEYPrivate key from this demo brand's Klaviyo account (Settings, API keys) with Read Access on Accounts, Campaigns, Flows and Metrics. Keys can't be edited later, so pick all four. another brand's keys are refused.
RECHARGE_API_TOKENOnly if subscriptions move to Recharge. Subscriptions sold through Seal or any app using Shopify subscription contracts are already counted from the sales reports.
FEATURE_TRACKING_KEY / STOREFRONT_ORIGINBearer key the storefront uses to post feature events, and the origin allowed to post (https://northbank.example.com).
SHOPIFY_ADMIN_TOKENOnly for a legacy custom app made in the Shopify admin before 2026. Leave blank when using the Dev Dashboard app.

How the numbers are built

So nobody has to guess what a figure means.

  • Sales, orders, units, new vs returning and product mix come from Shopify's own reports (ShopifyQL), so they line up with Shopify analytics.
  • Net sales are after discounts and returns, before tax and shipping.
  • Sessions, the funnel and conversion rate exclude bot sessions. Conversion rate is sessions that completed checkout divided by sessions.
  • Channels use Shopify's traffic type and referring medium. AI Referral uses Shopify's AI agent tag plus referrer domains such as Perplexity and Claude.
  • Duos, edits and collections count as bundles. Free gift lines are shown in grey so they don't read as best sellers.
  • Subscription panels stay hidden until subscription orders appear in Shopify or a Recharge token is added.
  • Recent ranges refresh every 15 minutes. Older ranges are cached for six hours.

Persistence

Tickets and feature counters need somewhere to live.

In the Vercel project open Storage, add a new Redis database on the free plan, and connect it to this project. Vercel adds REDIS_URL and the next deploy keeps everything. Don't connect another brand's store: each dashboard keeps its own tickets. Until then tickets live in memory and reset on each deploy.

Targets

Where the plan numbers come from.

No plan loaded yet, so the plan bars and Pace to plan stay hidden. Send the monthly plan (net sales and orders per month) and scripts/targets_from_csv.py turns it into data/targets.json.

Cross Street Coffee · That Other Agency