Hardik Dewra

3 min read

How to run Framer landing pages on a Shopify store

Framer for the campaign pages, Shopify for cart and checkout, a cart permalink in between. The setup, the tracking fix, and when Framer is wrong.

Build your Framer landing pages for campaigns, and keep the cart and checkout inside your Shopify store. A cart permalink carries the buyer across and fills their cart for them. Two things break this setup. Your analytics gets confused by two domains, and your prices drift apart. You can fix both in an afternoon.

Split your Framer landing pages from your Shopify store

Framer takes the pages you change often and want design freedom on: campaign landing pages, advertorials, the brand story, launch pages and quiz results. Shopify keeps everything to do with money: product pages, collections, cart, checkout, customer accounts and order status. Do not rebuild checkout.

The split works because the two sets do different jobs and get edited at very different rates. You will ship four landing page variants this month, and touch checkout zero times.

The handoff is a cart permalink

Shopify documents a URL format that fills a cart straight from a link. Point your Framer button at yourstore.com/cart/VARIANT_ID:QUANTITY. Add a discount with ?discount=CODE. Add more than one item with a comma, like /cart/11111:1,22222:2. Add ?storefront=true if you want the buyer to land on the cart page instead of going straight to checkout.

You find the variant ID in the Shopify admin URL when you open a variant. Keep one permalink per offer in a shared note. A wrong variant ID sends every buyer to the wrong pack size, and you will not spot it until the fulfilment report.

Fix tracking before you spend a dollar on ads

This is where most Framer plus Shopify setups quietly break. The visitor starts on your Framer domain and finishes on Shopify checkout. Without the right configuration, GA4 counts one session as two, and Meta loses the link between the click and the purchase.

Do four things. Add both domains to the GA4 cross domain measurement list, or put both on the same root domain. Install the Meta pixel in Framer, and again through Shopify Customer Events. Pass your UTMs through the permalink so the source survives the jump. Then make one real test purchase and confirm it shows up once in GA4 and once in Meta, not twice and not zero times.

Keep the price honest in two systems

The moment your Framer page says 49 dollars and Shopify charges 54, you get refund requests and a review problem. Write the price in exactly one place per page. Never put it inside an exported image, and never inside the hero graphic that took you two hours to make.

Once you pass three landing pages, move the offer into a Framer CMS collection with fields for price, compare at price, permalink and stock status. One edit then updates every page. Set a monthly reminder to open each live page next to its Shopify product and check the two agree.

Protect the speed you paid for

Framer pages start fast. Then somebody adds a chat widget, a heatmap recorder, two pixels and a review embed, and the hero takes four seconds on 4G. Google's Largest Contentful Paint threshold is 2.5 seconds at the 75th percentile of real mobile visits. That is your budget for the whole page.

Serve the hero image at the size it really renders. Skip lazy loading on it. Load review widgets below the fold only. Test on a real phone over throttled mobile data rather than on a desktop over office wifi.

When Framer is the wrong tool

A catalogue of 200 SKUs with filtering, search and daily stock changes belongs in Shopify, with Framer used only for the campaign pages. Framer earns its place where design quality and iteration speed decide the outcome, and that means landing pages rather than catalogue browsing.

The setup, in order

Connect your Framer domain. Build one landing page and one cart permalink. Add the pixel on both platforms and pass UTMs through the link. Make one real purchase and follow it through GA4, Meta and the Shopify order. Only then point ad spend at it.

Budget a day for that first page and an hour for every page after it. Speed is the whole reason to run this stack, so a new angle should go live in an afternoon instead of a sprint.