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

# Build an Advertorial

> Build an editorial-style page that tells a story and presells your product.

export const TryPromptButton = ({prompt, imageSrc, imageAlt = "Template preview", imageStyles = {}, buttonCta = "Build in Replo"}) => {
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(null);
  const API_BASE = "https://api.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(`${API_BASE}/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");
      setIsLoading(false);
    } catch (caughtError) {
      console.error("Failed to generate prompt:", caughtError);
      const message = caughtError instanceof Error ? caughtError.message : null;
      setError(message ?? "Something went wrong. Please try again.");
      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>;
};

<TryPromptButton prompt="Build this page exactly https://order.uprootclean.com/wmtabs/wmt004-3, with images" imageSrc="/images/use-cases/advertorial/cover.png" buttonCta="Build in Replo" imageStyles={{ borderRadius: "0.5rem" }} imageAlt="Advertorial" />

## What Is an Advertorial?

An advertorial is an ad that doesn't look like an ad.

It looks like an article. Or a customer story. Or an educational guide. But it's selling something.

The name comes from combining "advertisement" and "editorial." You're advertising, but it reads like editorial content.

Here's why that matters.

## Why Advertorials Work

Nobody clicks on ads anymore. People have learned to ignore them. Studies show users spend less than 1% of their attention on typical ad placements. Hundreds of millions of people use ad blockers. Your banner ads aren't working.

But people do read articles. They read stories. They read guides that help them solve problems. Advertorials work because they give people something valuable before asking for anything. You're not interrupting them. You're helping them.

## When to Use Advertorials

Advertorials work best when you need to explain something. If you're selling a simple product everyone understands, you probably don't need one. Just show them the product and the price.

But if you're selling something that requires explanation, advertorials are powerful:

* Products that solve unfamiliar problems
* Premium products where price needs justification
* Complex products with benefits that aren't obvious
* New products in crowded categories

The more explaining you need to do, the more an advertorial helps.

## The Basic Formula

Good advertorials follow a simple structure:

1. Start with a problem people have
2. Give them valuable information about that problem
3. Show how your product solves it
4. Make it easy to buy

The key is step #2. You need to actually help people. Give them information they'd want to read even if they never buy from you.

Spend 75% of your page delivering value. Spend 25% selling.

If you flip those numbers, you've just made a sales page. Nothing wrong with sales pages, but that's not an advertorial.

# What we're building today

Today we're gonna build an advertorial landing page for a washing machine cleaner as an example. This is a perfect example of the format done right.

## Prompt

```
Build this page exactly https://order.uprootclean.com/wmtabs/wmt004-3, with images
```

## Step #1: Building this page in Replo

Copy the above prompt directly into the chat in Replo. Replo will spend a few minutes building the page for you, pulling in the sections, images, and copy from the reference.

## Step #2: Use select mode to directly update the content

Now that the page is built, you can use select mode to edit the page precisely. Select mode gives you a direct way to click into elements on your page and target them with edits: select an element, then describe the change in plain language and Replo updates exactly that element.

To learn more, please read our [select mode](/features/edit-mode) documentation.

## Step #3: Publish the page

Now that the page is updated, you can publish it to your website. Publishing your pages makes them live on your site. Your published page will be accessible to anyone with the link; make sure your site is ready for public access before publishing!
