> ## Documentation Index
> Fetch the complete documentation index at: https://beta.docs.replo.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Why Publish to a Subdomain

> Understand why Replo pages live on a subdomain, what stays on Shopify, and how tracking, ads, and checkout keep working.

export const Screenshot = ({src, altText, width, shadow = true}) => {
  const generateAltText = imageSrc => {
    if (!imageSrc) return "Screenshot";
    const filename = imageSrc.split("/").pop() ?? "";
    const nameWithoutExt = filename.replace(/\.[^/.]+$/, "");
    const readable = nameWithoutExt.replace(/[-_]/g, " ").replace(/\b\w/g, char => char.toUpperCase());
    return readable === "" ? "Screenshot" : readable;
  };
  const finalAltText = altText ?? generateAltText(src);
  const imageWidth = width ? `${width}px` : "100%";
  return <div style={{
    position: "relative",
    width: "100%",
    borderRadius: "12px",
    overflow: "hidden",
    boxSizing: "border-box",
    display: "flex",
    justifyContent: "center"
  }}>
      {}
      <svg style={{
    position: "absolute",
    top: 0,
    left: 0,
    width: "100%",
    height: "100%",
    zIndex: 0,
    pointerEvents: "none"
  }} viewBox="0 0 1920 1080" fill="none" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid slice">
        <g clipPath="url(#clip0_5067_2569)">
          <rect width="1920" height="1080" fill="black" />
          <g opacity="0.9" filter="url(#filter0_fn_5067_2569)">
            <mask id="mask0_5067_2569" style={{
    maskType: "alpha"
  }} maskUnits="userSpaceOnUse" x="539" y="-367" width="2018" height="1261">
              <rect x="539" y="-367" width="2017.6" height="1261" fill="#C4C4C4" />
            </mask>
            <g mask="url(#mask0_5067_2569)">
              <g filter="url(#filter1_f_5067_2569)">
                <path d="M880.949 82.6474L1798.19 -385.441L2215.11 -385.441L2725.35 -260.618L936.539 437.057L880.949 82.6474Z" fill="url(#paint0_linear_5067_2569)" />
              </g>
              <g filter="url(#filter2_f_5067_2569)">
                <ellipse cx="462.152" cy="150.719" rx="462.152" ry="150.719" transform="matrix(0.914846 -0.403803 0.330497 0.943807 1250.96 112.228)" fill="#FEBC2E" />
              </g>
              <g filter="url(#filter3_f_5067_2569)">
                <path d="M1687.1 56.3942C2102.4 -149.497 2274.54 -159.301 2672.61 -80.8668L2803.87 183.851L884.491 784.367C849.346 777.831 951.195 612.791 1228.77 362.78C1281.1 315.653 1271.81 262.285 1687.1 56.3942Z" fill="url(#paint1_linear_5067_2569)" />
              </g>
              <g opacity="0.7" filter="url(#filter4_f_5067_2569)">
                <path d="M1975.09 -76.9728C2367.51 -238.299 2270.38 -191.657 2637.67 -120.329L2758.78 120.402L1001.73 662.047C969.304 656.104 932.244 530.091 1043.42 349.988C1182.4 124.86 1518.29 110.824 1975.09 -76.9728Z" fill="#B7FEAE" fillOpacity="0.5" />
              </g>
              <g filter="url(#filter5_f_5067_2569)">
                <path d="M2052.63 99.5535C2383.11 16.7587 2366.44 -59.7112 2665.61 -7.17013L2707.81 170.156L1276.64 569.14C1250.23 564.762 1220.04 471.939 1310.6 339.273C1423.8 173.44 1803.59 161.946 2052.63 99.5535Z" fill="#EF196E" />
              </g>
              <g opacity="0.4" filter="url(#filter6_f_5067_2569)">
                <ellipse cx="462.152" cy="218.806" rx="462.152" ry="218.806" transform="matrix(0.914846 -0.403803 0.330497 0.943807 1152.46 417.938)" fill="#FFEB80" />
              </g>
              <g filter="url(#filter7_f_5067_2569)">
                <ellipse cx="462.152" cy="150.719" rx="462.152" ry="150.719" transform="matrix(0.914846 -0.403803 0.330497 0.943807 1913.18 237.904)" fill="#B7FEAE" />
              </g>
              <g filter="url(#filter8_f_5067_2569)">
                <g opacity="0.4" filter="url(#filter9_f_5067_2569)">
                  <path d="M1551.1 493.269L2619.23 -0.477507L3125.23 -71.2418L3756.49 -67.6927L1652.68 739.798L1551.1 493.269Z" fill="url(#paint2_linear_5067_2569)" />
                </g>
              </g>
              <g filter="url(#filter10_f_5067_2569)">
                <g opacity="0.4" filter="url(#filter11_f_5067_2569)">
                  <path d="M1696.12 652.03L2820.04 310.947L3330.91 310.947L3956.12 401.903L1764.24 910.278L1696.12 652.03Z" fill="url(#paint3_linear_5067_2569)" />
                </g>
                <g opacity="0.4" filter="url(#filter12_f_5067_2569)">
                  <path d="M1628.55 727.676L2843.38 257.743L3271.53 195.271L3903.03 210.271L1788.72 978.91L1628.55 727.676Z" fill="url(#paint4_linear_5067_2569)" />
                </g>
              </g>
            </g>
          </g>
        </g>
        <defs>
          <filter id="filter0_fn_5067_2569" x="637.809" y="-607" width="2158.79" height="1741" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
            <feFlood floodOpacity="0" result="BackgroundImageFix" />
            <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
            <feGaussianBlur stdDeviation="120" result="effect1_foregroundBlur_5067_2569" />
            <feTurbulence type="fractalNoise" baseFrequency="1 1" stitchTiles="stitch" numOctaves="3" result="noise" seed="7978" />
            <feColorMatrix in="noise" type="luminanceToAlpha" result="alphaNoise" />
            <feComponentTransfer in="alphaNoise" result="coloredNoise1">
              <feFuncA type="discrete" tableValues="1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 " />
            </feComponentTransfer>
            <feComposite operator="in" in2="effect1_foregroundBlur_5067_2569" in="coloredNoise1" result="noise1Clipped" />
            <feFlood floodColor="rgba(0, 0, 0, 0.25)" result="color1Flood" />
            <feComposite operator="in" in2="noise1Clipped" in="color1Flood" result="color1" />
            <feMerge result="effect2_noise_5067_2569">
              <feMergeNode in="effect1_foregroundBlur_5067_2569" />
              <feMergeNode in="color1" />
            </feMerge>
          </filter>
          <filter id="filter1_f_5067_2569" x="878.4" y="-387.991" width="1849.5" height="827.597" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
            <feFlood floodOpacity="0" result="BackgroundImageFix" />
            <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
            <feGaussianBlur stdDeviation="1.27461" result="effect1_foregroundBlur_5067_2569" />
          </filter>
          <filter id="filter2_f_5067_2569" x="1129.77" y="-334.846" width="1187.61" height="805.41" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
            <feFlood floodOpacity="0" result="BackgroundImageFix" />
            <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
            <feGaussianBlur stdDeviation="84.0203" result="effect1_foregroundBlur_5067_2569" />
          </filter>
          <filter id="filter3_f_5067_2569" x="855.856" y="-148.194" width="1969.97" height="954.514" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
            <feFlood floodOpacity="0" result="BackgroundImageFix" />
            <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
            <feGaussianBlur stdDeviation="10.9761" result="effect1_foregroundBlur_5067_2569" />
          </filter>
          <filter id="filter4_f_5067_2569" x="958.113" y="-196.498" width="1811.26" height="869.143" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
            <feFlood floodOpacity="0" result="BackgroundImageFix" />
            <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
            <feGaussianBlur stdDeviation="5.29875" result="effect1_foregroundBlur_5067_2569" />
          </filter>
          <filter id="filter5_f_5067_2569" x="1149.75" y="-124.443" width="1658.06" height="793.583" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
            <feFlood floodOpacity="0" result="BackgroundImageFix" />
            <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
            <feGaussianBlur stdDeviation="50" result="effect1_foregroundBlur_5067_2569" />
          </filter>
          <filter id="filter6_f_5067_2569" x="1098.27" y="39.191" width="1098.61" height="797.277" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
            <feFlood floodOpacity="0" result="BackgroundImageFix" />
            <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
            <feGaussianBlur stdDeviation="60.1484" result="effect1_foregroundBlur_5067_2569" />
          </filter>
          <filter id="filter7_f_5067_2569" x="1886.85" y="-114.306" width="997.881" height="615.684" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
            <feFlood floodOpacity="0" result="BackgroundImageFix" />
            <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
            <feGaussianBlur stdDeviation="36.5888" result="effect1_foregroundBlur_5067_2569" />
          </filter>
          <filter id="filter8_f_5067_2569" x="1540.3" y="-82.0399" width="2226.99" height="832.636" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
            <feFlood floodOpacity="0" result="BackgroundImageFix" />
            <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
            <feGaussianBlur stdDeviation="5.39908" result="effect1_foregroundBlur_5067_2569" />
          </filter>
          <filter id="filter9_f_5067_2569" x="1547.97" y="-74.3651" width="2211.64" height="817.287" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
            <feFlood floodOpacity="0" result="BackgroundImageFix" />
            <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
            <feGaussianBlur stdDeviation="1.56172" result="effect1_foregroundBlur_5067_2569" />
          </filter>
          <filter id="filter10_f_5067_2569" x="1598.84" y="165.553" width="2387" height="843.074" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
            <feFlood floodOpacity="0" result="BackgroundImageFix" />
            <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
            <feGaussianBlur stdDeviation="14.8586" result="effect1_foregroundBlur_5067_2569" />
          </filter>
          <filter id="filter11_f_5067_2569" x="1693" y="307.824" width="2266.24" height="605.577" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
            <feFlood floodOpacity="0" result="BackgroundImageFix" />
            <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
            <feGaussianBlur stdDeviation="1.56172" result="effect1_foregroundBlur_5067_2569" />
          </filter>
          <filter id="filter12_f_5067_2569" x="1617.84" y="184.562" width="2295.9" height="805.057" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
            <feFlood floodOpacity="0" result="BackgroundImageFix" />
            <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
            <feGaussianBlur stdDeviation="5.35445" result="effect1_foregroundBlur_5067_2569" />
          </filter>
          <linearGradient id="paint0_linear_5067_2569" x1="1803.15" y1="-385.441" x2="1040.5" y2="259.543" gradientUnits="userSpaceOnUse">
            <stop stopColor="#FF7D54" />
            <stop offset="1" stopColor="white" stopOpacity="0" />
          </linearGradient>
          <linearGradient id="paint1_linear_5067_2569" x1="2283.14" y1="-17.1385" x2="1351.98" y2="310.625" gradientUnits="userSpaceOnUse">
            <stop stopColor="#B7FEAE" />
            <stop offset="0.65537" stopColor="#EF196E" />
            <stop offset="1" stopColor="#274AE2" />
          </linearGradient>
          <linearGradient id="paint2_linear_5067_2569" x1="2625.25" y1="-1.32004" x2="2201.56" y2="820.649" gradientUnits="userSpaceOnUse">
            <stop stopColor="#3A4CF0" />
            <stop offset="1" stopColor="#F5FAD9" stopOpacity="0" />
          </linearGradient>
          <linearGradient id="paint3_linear_5067_2569" x1="2826.12" y1="310.947" x2="2295.81" y2="1065.13" gradientUnits="userSpaceOnUse">
            <stop stopColor="#EF196E" />
            <stop offset="1" stopColor="white" stopOpacity="0" />
          </linearGradient>
          <linearGradient id="paint4_linear_5067_2569" x1="2452.05" y1="509.031" x2="2135.78" y2="1074.58" gradientUnits="userSpaceOnUse">
            <stop offset="0.166667" stopColor="#EF196E" />
            <stop offset="0.541667" stopColor="#FFEB80" stopOpacity="0.25" />
            <stop offset="1" stopColor="#274AE2" stopOpacity="0" />
          </linearGradient>
          <clipPath id="clip0_5067_2569">
            <rect width="1920" height="1080" fill="white" />
          </clipPath>
        </defs>
      </svg>

      {}
      <div style={{
    position: "relative",
    zIndex: 1,
    padding: "clamp(24px, 4vw, 48px)",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    width: "100%"
  }}>
        <img src={src} alt={finalAltText} style={{
    width: imageWidth,
    maxWidth: "100%",
    height: "auto",
    display: "block",
    borderRadius: "8px",
    boxShadow: shadow ? "0 20px 60px rgba(0, 0, 0, 0.3)" : "none"
  }} />
      </div>
    </div>;
};

Replo publishes your pages to a subdomain of your own domain (for example, `shop.yourbrand.com`) instead of into your Shopify theme. If your first reaction is "I don't want a subdomain, I want to publish to Shopify," this page explains why the subdomain exists, what actually changes (less than you'd expect), and the few cases where a subdomain genuinely isn't the right tool.

The short version: your Shopify store stays your Shopify store. Products sync from Shopify, every add to cart writes to a real Shopify cart behind the scenes, checkout happens on Shopify checkout, and orders land in your Shopify admin like any other order.

The cart drawer a visitor sees is Replo's (rebuilt to match yours, if you want); the cart data, checkout, and orders are Shopify's. The only thing that moves is where the page itself is hosted.

## What a subdomain is

A subdomain is a section of the domain you already own. If your store is `yourbrand.com`, then `shop.yourbrand.com` is a subdomain of it. It's not a new domain, a Replo-branded URL, or a third-party address; it's your brand in the address bar, controlled by one DNS record you add at your domain provider.

Browsers and ad platforms treat subdomains as part of the same site for the things that matter to marketers: cookies set by Meta and Google Analytics are shared across `yourbrand.com` and `shop.yourbrand.com`, and Meta's domain verification for `yourbrand.com` covers every subdomain automatically (details below).

## Why Replo pages don't publish into your theme

Your root domain points at Shopify, and Shopify only serves Liquid theme code from it. Replo pages are modern web apps: server-rendered React, deployed to Cloudflare's edge network. That architecture is what makes the pages fast and lets Replo build and edit them for you in chat, and it can't be uploaded into a Liquid theme.

So the page needs its own address, and a subdomain of your existing domain is the address that keeps your brand, your cookies, and your ad account verification intact.

The separation also works in your favor:

* **No theme risk.** Nothing Replo publishes can touch your theme, navigation, or existing pages. Test aggressive offers freely.
* **No app bloat.** Your theme loads every app script you've ever installed. Replo pages load only what's on the page, which is a big part of why they're fast. See [Page Speed](/features/page-speed).
* **Campaign independence.** Marketing ships landing pages without waiting on whoever owns the theme, and without a deploy that could break the store.

If you need pages that live inside your theme (sections, blog posts, product templates), that's what the [Replo Theme Builder](/getting-started/sites-vs-themes) is for. The two products work side by side.

## What stays on Shopify

Connecting Shopify to Replo means the commerce layer is Shopify's, regardless of where the page is hosted:

* **Products**: your catalog syncs automatically, including variants, selling plans, inventory, and pricing. Changes sync within about 5 minutes; cart prices and inventory are always real time.
* **Cart**: the slide-out cart on a Replo page is Replo's own cart UI, and you can have Replo recreate your theme's cart design, including its upsells and messaging. Underneath, every add to cart writes to a real Shopify cart through Shopify's Storefront API, the same mechanism headless storefronts use, which is why discount codes and Shop Pay work at checkout.

  One nuance: this cart is separate from a cart the same visitor may have started on your theme site, so items don't merge across the two; each funnel checks out with what was added in it.
* **Checkout**: customers check out on your Shopify checkout, with Shop Pay, discount codes, and your checkout apps.
* **Orders and automations**: orders appear in your Shopify admin like any other order. Abandoned cart emails, confirmation flows, and segmentation keep working because the cart and order data live in Shopify.

For the full picture, see [Selling with Shopify](/commerce/shopify).

## Setup is about five minutes, and Replo walks you through it

If you've never set up a subdomain, this is probably the part that feels daunting, especially when your current stack already works and you know your Shopify publishing flow cold. So here is the entire setup, start to finish:

1. **Tell Replo the subdomain you want** (say `shop.yourbrand.com` in chat, or type it in Site settings → **Domains**).
2. **Copy one DNS record.** Replo shows you the exact record (a CNAME) with the exact values. You paste it into your domain provider (GoDaddy, Namecheap, Cloudflare, or Shopify admin if Shopify manages your DNS).
3. **Click Check Connection.** Replo verifies the record and provisions the SSL certificate automatically. There is nothing to buy, renew, or maintain.

That's the whole thing: about five minutes of actual work, and if it takes longer, the extra time is DNS propagation (waiting, not doing). If you get stuck on step 2, ask Replo in chat; it will tell you exactly where to click for your specific domain provider.

<Screenshot src="/images/cropped/site-settings-domains.png" altText="The Domains tab in Site settings, showing a verified domain and a field to add a custom domain with a Connect button" />

Two more fears worth putting down:

* **You don't have to touch DNS to start.** Every site publishes to a free `replosites.com` staging domain with zero setup. Build, publish, and share pages there today, and connect the subdomain whenever you're ready to run traffic.
* **You're not learning a new publishing flow.** There's no theme editor equivalent to master. You describe the page, Replo builds it, and publishing is one click (or just ask). If anything, it's fewer steps than the flow you already know.

The full walkthrough with screenshots is in [Custom Domains](/custom-domains).

## Common concerns, answered

<AccordionGroup>
  <Accordion title="Won't I have to redo domain verification with Meta?">
    No. Meta verifies domains at the root, and verification is inherited by every subdomain. Meta's developer FAQ states it directly: "domain verification status is inherited by subdomains. For example, verifying 'domain.com' will also verify 'm.domain.com'." Meta's [domain verification instructions](https://www.facebook.com/business/help/321167023127050) work the same way: you enter the root domain without any prefixes when you verify.

    If `yourbrand.com` is already verified in your Business Manager, `shop.yourbrand.com` is covered, with nothing new to verify.

    The one exception, from that same Meta help page: "You'll only need to verify subdomains when you're onboarding to Facebook Commerce." That's Shops onboarding, unrelated to running ads to a landing page.
  </Accordion>

  <Accordion title="Will my Meta Pixel and tracking break?">
    No, and this is worth understanding precisely because it's the most common worry.

    The Meta Pixel identifies visitors with the `_fbp` cookie, which is a first-party cookie set at your root domain. That means the same visitor identity is shared across `yourbrand.com`, `shop.yourbrand.com`, and your Shopify checkout. A visitor who lands on your Replo page from an ad and buys through your checkout is one person to Meta, not two.

    Setup is the same pixel IDs you already use, added once in your site's **Scripts & Pixels** settings (or ask Replo in chat). Replo supports Meta, GA4, Google Tag Manager, TikTok, Pinterest, Snapchat, Reddit, and more; see [Integrations](/integrations/introduction).

    <Screenshot src="/images/cropped/site-settings-pixels.png" altText="The Scripts & Pixels tab in Site settings, with a cookie consent control and built-in entries for Google Analytics, Google Tag Manager, Meta, TikTok, Pinterest, Reddit, and Snapchat" />

    Two things Replo does for you automatically:

    * **Every query parameter follows the visitor to checkout.** UTMs and click IDs (`fbclid`, `gclid`, and everything else on the landing URL) are carried onto the Shopify checkout URL, so attribution survives the handoff from your Replo page to Shopify.
    * **No double counting.** When checkout is Shopify-hosted, Shopify's native ad-platform integrations already report checkout and purchase events, so Replo's pixels suppress their duplicates.

    One honest caveat: page views on your Replo pages show up in Replo's analytics and your GA4/pixel dashboards, not in Shopify's built-in Analytics reports (Shopify only reports on pages it hosts). Orders, revenue, and conversion attribution in Shopify are unaffected.

    You don't have to take any of this on faith. Before you launch, ask Replo to audit your tracking setup:

    ```text theme={null}
    Audit my tracking setup before I drive paid traffic. Compare the pixels installed on this site against my main store at yourbrand.com, list anything missing, and flag anything that would break attribution.
    ```

    Replo reads your **Scripts & Pixels** configuration, compares it against your live store, and tells you exactly what to fix, so "did I set this up right?" gets a concrete answer instead of a guess.
  </Accordion>

  <Accordion title="What about GA4?">
    GA4 handles subdomains automatically. Its default `cookie_domain` setting stores the analytics cookie at your root domain, so the same measurement ID tracks one visitor across `yourbrand.com` and `shop.yourbrand.com` with no cross-domain configuration. Google documents this in the [GA4 configuration reference](https://developers.google.com/analytics/devguides/collection/ga4/reference/config). Use the same measurement ID on both, and you're done.
  </Accordion>

  <Accordion title="Will Triple Whale, Northbeam, or my attribution tool break?">
    These tools attribute with the same building blocks: their pixel on the page, plus UTMs and click IDs surviving to checkout. Add their snippet in **Scripts & Pixels** (Triple Whale and Northbeam are supported alongside the ad-platform pixels), keep UTMs on your ad URLs as usual, and Replo forwards everything to checkout. If your attribution tool has a setup checklist for landing page domains, it takes the subdomain the same way it takes your root domain.
  </Accordion>

  <Accordion title="Do I need to restart my ad sets or re-enter Meta's learning phase?">
    Pointing an ad at a new landing page URL is the same operation whether that page is `yourbrand.com/pages/offer` or `shop.yourbrand.com/offer`: a new ad or an edited destination behaves the same either way. There's no domain-level penalty, allowlist, or review triggered by using your verified domain's subdomain. Google Ads destination requirements are also satisfied because the display and destination domains match your brand.
  </Accordion>

  <Accordion title="Will this hurt my SEO?">
    For the pages you'd build in Replo (paid landing pages, campaign funnels, advertorials), SEO usually isn't the goal, and you can keep them out of search entirely with per-page indexing controls; see [Site & Page Settings](/features/site-page-settings).

    For search itself, Google's official position is that subdomains and subdirectories are [equivalent for crawling and ranking](https://developers.google.com/search/help/crawling-index-faq). The honest nuance: a subdomain builds its own authority rather than inheriting your root domain's, so content whose job is organic growth (your blog, your collection pages) belongs on your main site.

    That's a reason to keep SEO content where it is, not a reason to avoid subdomains for campaign pages. Replo sites also generate their own sitemap and robots rules automatically.
  </Accordion>

  <Accordion title="I have custom messaging and upsells in my cart. Do I lose them?">
    You rebuild them once, and rebuilding is fast. The cart drawer on a Replo page is Replo's own UI (your theme's cart can't render outside your theme), backed by a real Shopify cart underneath.

    Point Replo at your live site and ask it to recreate your cart's design, including gift-with-purchase logic, upsells, and promotional messaging. Metafield-driven offers can read the same metafields your theme cart uses, so you control both from one place. Many teams get an exact copy of their theme cart in one session.
  </Accordion>

  <Accordion title="Isn't setting up a subdomain a lot of work?">
    It's one DNS record and about five minutes of work; [the setup section above](#setup-is-about-five-minutes-and-replo-walks-you-through-it) lists all three steps. And if you're not ready to touch DNS at all, publish to your free `replosites.com` staging domain first and connect the subdomain when you want to run traffic.
  </Accordion>

  <Accordion title="Will customers be confused by a different URL?">
    Customers see your brand in the address bar (`shop.yourbrand.com`), then check out on your normal checkout. Subdomains are standard practice across ecommerce: brands routinely run stores, campaign pages, and content on subdomains, and paid traffic in particular never notices, because visitors arrive from an ad and leave through checkout without ever typing a URL.
  </Accordion>

  <Accordion title="We just don't use subdomains. Why start now?">
    "Keep everything in one place" is a fair instinct, but the place your pages live and the place your commerce lives are already separate concerns; Shopify itself hosts your checkout on different infrastructure than your theme.

    The subdomain buys you real things: pages that load without your theme's app scripts, campaigns that can't break your store, and a build workflow where you describe the page instead of assembling it. The setup cost is one DNS record; the concerns that make subdomains feel risky (tracking, ads, checkout) are covered above, with sources.
  </Accordion>
</AccordionGroup>

## When a subdomain isn't the right choice

Some pages should live inside your Shopify theme, and a subdomain is the wrong tool for them:

* **Core product and collection pages** that need your theme's navigation, search, and installed theme apps around them.
* **SEO content** (blog posts, buying guides) whose job is building your root domain's authority.
* **Pages that depend on theme-specific Liquid** or apps that only render inside a Shopify theme.

For those, use the [Replo Theme Builder](/getting-started/sites-vs-themes), which publishes directly into your theme on your store's domain. Teams commonly run both, and it isn't an even split: the Theme Builder handles the pages that must live in your theme, and Replo Agent does everything else.

That's because publishing pages is only one part of what Replo Agent does. The same chat captures your brand kit and guidelines and applies them to every page you build, audits your tracking setup before you spend on ads, duplicates landing pages into A/B variants and designs the test so the result is trustworthy, reads your analytics and builds reports on demand, and runs scheduled tasks (weekly performance summaries, broken-link checks) in the background. [Common Workflows](/use-cases/workflows) shows each of these in practice.

The subdomain is just where the pages live; the agent working across your whole funnel is what you're actually getting.

## Before you drive paid traffic

A short checklist so the first campaign is attributed correctly:

1. **Connect and verify your subdomain** in Site settings → **Domains** ([Custom Domains](/custom-domains)).
2. **Add your pixels** in **Scripts & Pixels**: the same Meta, GA4, TikTok, and attribution-tool IDs you use on your main store ([Integrations](/integrations/introduction)).
3. **Ask Replo to audit the setup** against your main store (the prompt is in the tracking question above). Fix anything it flags.
4. **Keep UTMs on your ad URLs** exactly as you do today. Replo forwards them (and click IDs) through to checkout.
5. **Click through the funnel once**: land on the published page with test UTMs, add to cart, and reach checkout. Confirm your pixel events fire and the parameters arrive.
6. **Publish and launch.** Orders appear in your Shopify admin; page analytics appear in Replo's insights and your GA4.

## Next steps

<CardGroup cols={3}>
  <Card title="Custom Domains" icon="globe" href="/custom-domains">
    Connect your subdomain with one DNS record.
  </Card>

  <Card title="Selling with Shopify" icon="cart-shopping" href="/commerce/shopify">
    How products, cart, and checkout work end to end.
  </Card>

  <Card title="Page Speed" icon="gauge-high" href="/features/page-speed">
    Why Replo-hosted pages load fast.
  </Card>
</CardGroup>
