> ## 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.

# Common Workflows

> Copy the workflows brands run in Replo, from paid-social funnels to scheduled reports, each with a prompt to start from.

export const TryPromptButton = ({prompt, imageSrc, imageAlt = "Template preview", imageStyles = {}, buttonCta = "Build in Replo"}) => {
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(null);
  const PUBLISHER_API_BASE_URL = "https://publisher.replo.app";
  const APP_URL = "https://dashboard.replo.app";
  const LoaderIcon = <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{
    animation: "spin 1s linear infinite"
  }}>
      <path d="M21 12a9 9 0 1 1-6.219-8.56" />
    </svg>;
  const ChevronIcon = <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="m9 18 6-6-6-6" />
    </svg>;
  async function postJSON(url, body, headers = {}, timeoutMs = 120000) {
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
    try {
      const response = await fetch(url, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          ...headers
        },
        body: JSON.stringify(body ?? ({})),
        signal: controller.signal
      });
      const responseText = await response.text();
      if (!response.ok) throw new Error(`API Error: ${response.status}`);
      return responseText ? JSON.parse(responseText) : {};
    } finally {
      clearTimeout(timeoutId);
    }
  }
  async function handleTryPrompt(event) {
    event.preventDefault();
    event.stopPropagation();
    setIsLoading(true);
    setError(null);
    try {
      const body = {
        prompt,
        file: null
      };
      const {seed} = await postJSON(`${PUBLISHER_API_BASE_URL}/api/v1/marketing/issue-marketing-site-jwt`, body);
      if (!seed) throw new Error("No seed returned from API");
      const url = new URL(APP_URL);
      url.searchParams.set("type", "agent");
      url.hash = `seed=${encodeURIComponent(seed)}`;
      window.open(url.toString(), "_blank");
    } catch (caughtError) {
      console.error("Failed to generate prompt:", caughtError);
      setError("Something went wrong. Please try again.");
    } finally {
      setIsLoading(false);
    }
  }
  return <div style={{
    position: "relative",
    display: "inline-block",
    width: "100%"
  }}>
      {}
      {imageSrc && <img src={imageSrc} alt={imageAlt} style={{
    width: "100%",
    height: "auto",
    display: "block",
    borderRadius: "8px",
    opacity: 0.8,
    ...imageStyles
  }} />}

      {}
      <div style={imageSrc ? {
    position: "absolute",
    top: "50%",
    left: "50%",
    transform: "translate(-50%, -50%)",
    zIndex: 10
  } : {
    display: "flex",
    justifyContent: "flex-start",
    margin: "1.25rem 0"
  }}>
        <button type="button" className="try-replo-btn" onClick={handleTryPrompt} disabled={isLoading} style={{
    backgroundColor: "#274AE2",
    color: "#ffffff",
    padding: "0.5rem 1.1rem",
    fontSize: "0.875rem",
    fontWeight: 600,
    fontFamily: "inherit",
    border: "none",
    borderRadius: "9999px",
    cursor: isLoading ? "not-allowed" : "pointer",
    lineHeight: 1.4,
    whiteSpace: "nowrap",
    display: "inline-flex",
    alignItems: "center",
    justifyContent: "center",
    WebkitFontSmoothing: "antialiased",
    boxSizing: "border-box",
    opacity: isLoading ? 0.7 : 1,
    boxShadow: "0 1px 2px rgba(15, 23, 42, 0.08)",
    transition: "background-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease"
  }}>
          <span style={{
    visibility: isLoading ? "hidden" : "visible",
    display: "inline-flex",
    alignItems: "center",
    gap: "0.375rem"
  }}>
            {buttonCta}
            {ChevronIcon}
          </span>
          {isLoading && <span style={{
    position: "absolute",
    display: "inline-flex",
    alignItems: "center",
    justifyContent: "center"
  }}>
              {LoaderIcon}
            </span>}
        </button>
      </div>

      {}
      <style>
        {`
          @keyframes spin {
            from {
              transform: rotate(0deg);
            }
            to {
              transform: rotate(360deg);
            }
          }
          .try-replo-btn:hover:not(:disabled) {
            background-color: #1f3ec0 !important;
            box-shadow: 0 4px 12px rgba(39, 74, 226, 0.35);
            transform: translateY(-1px);
          }
          .try-replo-btn:active:not(:disabled) {
            transform: translateY(0);
            box-shadow: 0 1px 2px rgba(15, 23, 42, 0.08);
          }
          .try-replo-btn:focus-visible {
            outline: 2px solid #274AE2;
            outline-offset: 2px;
          }
        `}
      </style>

      {}
      {error && <div style={{
    marginTop: "12px",
    padding: "12px 16px",
    backgroundColor: "#fee",
    border: "1px solid #fcc",
    borderRadius: "6px",
    color: "#c33",
    fontSize: "14px",
    textAlign: "center"
  }} role="alert">
          {error}
        </div>}
    </div>;
};

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>;
};

The guides in [Use Cases](/use-cases/introduction) each cover one page format. This page covers workflows: the end-to-end patterns brands run in Replo week after week, who runs each one, and what you can have working by the end of your first session.

Every workflow starts with a prompt you can copy into chat. Replace the bracketed parts with your own product, URL, or offer.

## Launch a paid-social funnel

Who runs it: a brand buying Meta or TikTok traffic (a bedding brand running ads into an advertorial, a supplement brand sending clicks to a listicle) that wants a dedicated page per ad angle instead of sending everyone to a product page.

Before you begin: connect a subdomain of your domain ([Custom Domains](/custom-domains)) and add the same pixels you use on your main store in **Scripts & Pixels** ([Integrations](/integrations/introduction)). [Why Publish to a Subdomain](/why-subdomains) explains how tracking and attribution carry through to checkout.

<Steps>
  <Step title="Build the page from the ad itself">
    Paste the ad creative into chat so the page matches the promise that earned the click:

    ```text theme={null}
    Here's the ad we're running [attach the ad image]. Build an advertorial
    landing page for @[product] that matches its offer and headline. Problem
    first, then the product, then reviews, then a buy section.
    ```

    If you run Google Ads, you can skip the pasting: connect it in the [Integrations app](/apps/integrations) and Replo reads your live campaigns directly in chat.

    ```text theme={null}
    Look at my active Google Ads campaigns and build a landing page matched
    to the messaging of my highest-spend ad group.
    ```
  </Step>

  <Step title="Audit tracking before you spend">
    Ask Replo to compare the pixels on the page against your main store and flag anything that would break attribution. See [the full pre-launch tracking checklist](/why-subdomains#before-you-drive-paid-traffic).
  </Step>

  <Step title="Publish and point the ad at the page">
    UTMs and click IDs on your ad URLs are forwarded through to checkout automatically.
  </Step>
</Steps>

The quick win: an ad-matched advertorial, live on your own domain, with tracking verified, in one session. For the format itself, see [Build an Advertorial](/use-cases/advertorials) and [Build a Listicle](/use-cases/listicle).

## Recreate your store's slide-out cart

Who runs it: a brand moving campaign traffic onto Replo pages that doesn't want to lose the cart experience its theme took months to tune (free-shipping progress bar, upsells, gift-with-purchase messaging).

Before you begin: connect Shopify ([Selling with Shopify](/commerce/shopify)). The cart drawer on a Replo page is Replo's own UI (which is why it needs recreating), but underneath, every add to cart writes to a real Shopify cart, so anything added on a Replo page lands in your normal checkout with your discount codes and cart-recovery emails intact.

```text theme={null}
Recreate the slide-out cart from [yourbrand.com], including the
free-shipping progress bar, the upsell section, and the promotional
messaging. Match the styling exactly.
```

Replo reads your live site and rebuilds the cart's design and offer logic on your Replo pages. If your cart is more complex, here's where the lines are:

* **Rebuilds cleanly**: the design and messaging, free-shipping progress bars, upsell sections, and gift-with-purchase promos. These are rebuilt as Replo's own logic on top of the real Shopify cart, so discount codes, subscriptions and selling plans, and line item properties all keep working.
* **Doesn't carry over as-is**: cart apps installed as Shopify theme embeds (UpCart and similar) only run inside a theme, so their widgets can't render on a Replo page. Replo rebuilds the same behavior natively instead. Some apps also have a direct integration: connect Rebuy in the [Integrations app](/apps/integrations), for example, and its product recommendations can power the upsells in your rebuilt cart.
* **Not sure which bucket you're in?** Ask before you commit:

```text theme={null}
Here's my current cart [screenshot or yourbrand.com]. Tell me what you can
recreate exactly, what you'd rebuild differently, and anything that won't
carry over.
```

The quick win: a cart your customers can't tell apart from the one on your store, so campaign pages stop feeling like a separate site.

## Give every email and SMS campaign its own page

Who runs it: a lifecycle marketer sending Klaviyo campaigns who is tired of pointing every send at the same collection page.

Before you begin: connect Klaviyo ([Klaviyo](/integrations/klaviyo)) so signup forms on your pages submit straight to your lists.

```text theme={null}
Build a landing page for our [spring restock] email campaign. Lead with
the same offer as the email ([20% off bundles]), feature @[product], and
end with an email signup form that adds new subscribers to my Klaviyo list.
```

The page matches the email that sent the visitor, and the signup form captures the people who arrived from a forward or a shared link. The quick win: your next campaign gets a destination built for it, not a generic page. Launching something new instead? Start with [Waitlist & Launch Pages](/use-cases/waitlist-preorders).

## Run a seasonal promo without touching your store

Who runs it: a brand running BFCM, a holiday drop, or a flash sale that wants the promo live fast and gone cleanly afterward, with zero risk to the theme.

Because Replo pages publish to your subdomain, nothing you build or unpublish can affect your store's theme or navigation. That makes aggressive, short-lived offers safe to ship.

```text theme={null}
Build a Black Friday page for @[collection]: a countdown to the end of
the sale, the discounted bundles up top, and urgency messaging throughout.
We'll turn it on Friday morning and off Monday night.
```

When the promo ends, unpublish the page or ask Replo to restore the evergreen version ([Version History](/features/version-history) keeps every edit reversible).

This is also where promo pages start compounding: once a layout converts, it becomes your template for every moment on the calendar. Duplicate the Black Friday page that worked, swap the offer, the countdown, and the imagery, and it's your Christmas page; then New Year's, then Valentine's Day. Each rerun takes minutes instead of a build cycle, so you can spend the saved time testing offers and creative, and your conversion rate improves promo over promo instead of starting from scratch each time.

The quick win: a promo page built and scheduled in a session, with a clean way back. Prompts for specific formats are in [Build a BFCM Campaign](/use-cases/bfcm) and [Build a Holiday Promotion Page](/use-cases/holiday-promotion).

## Start from a screenshot or a page you admire

Who runs it: anyone with a reference and no time to describe it: a founder who saw a competitor's funnel, a marketer with a Figma mock, a team with a page that already converts on another tool.

The prompt that gets the best results names the reference, what to keep, and what to make yours:

```text theme={null}
Build this page for my brand: [URL]. Keep the layout, section order, and
overall flow, but use @[product], my brand kit, and rewrite the copy for
[your offer].
```

Or paste a screenshot and scope it down:

```text theme={null}
Rebuild the hero and the comparison table from this screenshot for
@[product], in our brand colors.
```

Replo recreates the structure and adapts it to your brand kit and products; "keep the layout, change the brand" beats "copy this exactly," because an exact copy still carries the other brand's voice and offer. Cropped, focused screenshots give the most accurate results; the details are in [Generating Pages With Replo](/features/building-pages-ai). The quick win: the page you wished you had, rebuilt as your own, in minutes instead of a design cycle.

## Put reporting and upkeep on a schedule

Who runs it: a founder or marketer who wants the routine checks (traffic, broken links, stale content) to happen without them.

Before you begin: this is the workflow where connections pay off most. Connect [Slack](/integrations/slack) and reports land in the channel where your team already works instead of waiting in Replo. Connect [GA4](/integrations/ga4) or [Triple Whale](/integrations/triplewhale) and Replo can cross-reference its numbers against yours in the same report.

A [task](/apps/tasks) is a prompt with a schedule attached, so anything you'd ask Replo once, you can ask it weekly:

```text theme={null}
Every Monday at 9am, summarize last week's traffic, revenue, and
best-converting pages, flag anything that dropped, and post the report
to our #marketing channel in Slack.
```

<TryPromptButton prompt="Every Monday at 9am, summarize last week's traffic, revenue, and best-converting pages, flag anything that dropped, and post the report to our #marketing channel in Slack." />

```text theme={null}
Every Friday, check my published pages for broken links, outdated
promo dates, and slow images, and report what you find.
```

<TryPromptButton prompt="Every Friday, check my published pages for broken links, outdated promo dates, and slow images, and report what you find." />

Each run is a normal Replo session you can open and read, and a run can end in an action, not just a summary: post to Slack, or put a review meeting on the calendar with the [Google Calendar](/apps/integrations) connection when a number needs a human decision.

<Screenshot src="/images/cropped/tasks-schedule.png" altText="The Schedule view in the Tasks app showing a monthly calendar with a scheduled task" />

The quick win: your first Monday report arrives without you asking twice. [Sell at Scale](/use-cases/sell-at-scale) shows the full growth loop this plugs into.

## Run Replo from the tools you already use

Who runs it: a team that lives in Slack, Claude, or ChatGPT and doesn't want "check on the site" to mean opening another app.

Replo doesn't have to be a place you go. Two connections turn it into something you reach from wherever you already work:

* **Slack.** Connect [Slack](/integrations/slack) and @mention the Replo bot in any channel it's been added to. It runs a full Replo session right in the thread (edit the site, pull analytics, manage products, publish) and posts the result back, so a teammate can ship a copy change from the channel where the request came in.
* **Claude and ChatGPT.** Install the [Replo connector](/mcp/use-with-claude-and-chatgpt) and the AI you already use gets access to your Replo account: list and update your sites, manage products and scheduled tasks, query your analytics, and kick off full build sessions. If your briefs, research, and brand docs live in a Claude or ChatGPT workspace, draft there with all that context, then have it hand the finished brief straight to Replo to build.

```text theme={null}
@Replo update the hero headline on /black-friday to "48 hours only" and republish.
```

The quick win: the gap between "someone should do this" and "done" stops involving a login. For the full connector reference, see the [MCP overview](/mcp/overview).

## Test offers by splitting your ad traffic

Who runs it: a brand with real ad spend that wants to know whether the bundle or the subscription offer wins, without adding a testing tool.

The split happens in your ad platform: point two ads (or two ad sets) at two published pages. Replo's job is building the variants and keeping the test honest.

```text theme={null}
Duplicate our [bundle] landing page and change only the offer: the
variant should lead with [3 months free on the subscription] instead of
[15% off the bundle]. Keep everything else identical.
```

Then ask Replo to design and call the test. Replo's A/B testing [skill](/apps/skills) works out sample size and duration from your real traffic, and tells you when a result is trustworthy versus noise:

```text theme={null}
We're splitting ad traffic between /bundle and /bundle-subscription.
Our baseline conversion rate is [2.4%] on [1,200] visits a day. How long
do we run this, and what difference is big enough to call?
```

The quick win: a one-variable test designed correctly on day one, so you don't burn two weeks of spend on a result you can't trust.

## Next steps

<CardGroup cols={3}>
  <Card title="Use Cases" icon="layer-group" href="/use-cases/introduction">
    Prompts for each page format these workflows use.
  </Card>

  <Card title="Why Publish to a Subdomain" icon="globe" href="/why-subdomains">
    How tracking, ads, and checkout keep working.
  </Card>

  <Card title="Tasks" icon="clock" href="/apps/tasks">
    Schedule the recurring parts of any workflow.
  </Card>
</CardGroup>
