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

# Prompting 101

> Go from a blank chat to a landing page you'd actually ship, one prompt at a time.

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

The fastest way to learn prompting is to build something. This guide walks you through one campaign, a product launch page, from first prompt to shipped page. Every step has a prompt you can copy, use as-is, or adapt to your own product.

## Before you begin

You can follow along with any project. Results get noticeably better if you've set up your brand in [Brand Studio](/apps/brand-studio) and connected your products through [Integrations](/apps/integrations) first: Replo pulls your colors, fonts, product data, and checkout automatically instead of guessing.

## Step 1: Describe what you want built

Talk to Replo the way you'd brief a designer: what the page is for, who it's for, and what's on it. You don't need special syntax.

```text theme={null}
Build a launch landing page for my new lavender soy candle.
Audience is first-time visitors coming from Instagram ads.
Include a hero with the product photo, three benefit callouts, a reviews section, and one "Shop Now" button.
```

<TryPromptButton
  prompt={`Build a launch landing page for my new lavender soy candle.
Audience is first-time visitors coming from Instagram ads.
Include a hero with the product photo, three benefit callouts,
a reviews section, and one "Shop Now" button.`}
/>

Replo will start building and stream its work into the [Website Builder](/apps/website-builder) so you can watch. For bigger requests it drafts a [plan](/plans) first, so you can review the steps and redirect before it commits.

## Step 2: Add the context that changes the output

Replo follows what you say literally, so the details you give shape what you get. The three that matter most for a campaign page: **where the traffic comes from**, **what the offer is**, and **what counts as success**.

```text theme={null}
Traffic is cold, from TikTok, so keep it fast and mobile-first.
The offer is 20% off the first order.
The only goal on this page is clicks on "Shop Now", so keep it to a single CTA and no navigation links out.
```

<TryPromptButton
  prompt={`Traffic is cold, from TikTok, so keep it fast and mobile-first.
The offer is 20% off the first order.
The only goal on this page is clicks on "Shop Now", so keep it to a single CTA and no navigation links out.`}
/>

## Step 3: Iterate one change at a time

Once you're reacting to a real page, refine it with small, focused follow-ups. One change per prompt is easier for Replo to get right and easier for you to review.

```text theme={null}
Make the hero headline shorter and punchier, and move the reviews above the benefits section.
```

If the result isn't what you meant, say what's wrong and ask again. You don't need to start over; Replo keeps the rest of the page intact. Anything you want to undo lives in [Version History](/features/version-history).

## Step 4: Point at the exact element

When a request is about one specific thing on the page, don't describe where it is; select it. Turn on [select mode](/features/edit-mode) (the cursor icon in the composer), click the element, and your next message applies to exactly that.

```text theme={null}
Rewrite this to lead with the discount.
```

Selecting the element beats writing "the second button in the third section" every time.

## Step 5: Reference what you already have

Concrete references anchor the result far better than adjectives. Three kinds work especially well:

* **Your products.** Type `@` and pick a product; Replo pulls in real titles, images, prices, and variants, and wires the page to your checkout.
* **Images and ads.** Paste a screenshot of an ad or a page you like, and Replo matches the layout, tone, or palette. Pages that match the ad that sent the visitor convert meaningfully better than generic ones.
* **URLs.** Link to a reference site and say what to take from it: the whole layout, one section, or just the vibe.

```text theme={null}
Build a product page for @Lavender Candle that matches the attached ad creative: same headline promise, same warm color palette.
```

## Step 6: Say what not to do

Constraints keep pages focused and stop scope creep. State them as plainly as the asks.

```text theme={null}
Keep one CTA on the whole page. No pricing table, no related-products carousel, and don't change the hero image.
```

## Step 7: Ask Replo to sharpen your prompt

Not sure how to brief a new kind of campaign? Have Replo interrogate your prompt before building.

```text theme={null}
Review this prompt and tell me what's missing before you build it: "Build a landing page for a welcome offer with social proof and an email capture."
```

<TryPromptButton
  prompt={`Review this prompt and tell me what's missing before you build it:
"Build a landing page for a welcome offer with social proof and an email capture."`}
/>

It will come back asking about the offer, the audience, and the traffic source, and you'll have a stronger brief in one round trip.

## Step 8: Keep what works

When a page performs, turn its prompt into a reusable asset instead of reconstructing it from memory next quarter.

```text theme={null}
Summarize the launch page we just built as a reusable prompt I can run for future product launches.
```

For briefs you reuse constantly, go one step further and save it as a [skill](/apps/skills): a named routine Replo can run on demand, like `/launch-page` with your house style baked in.

## Pro tips

**Be specific about the change, not just the goal.**

Instead of: "make this page better"

Try: "tighten the hero copy to one sentence, make the benefits icon bullets, and move reviews above the fold"

**Number your steps for multi-part requests.** Replo mirrors your structure:

```text theme={null}
1. Hero: headline + subhead + CTA
2. Benefits: 3 icons with one-line descriptions
3. Social proof: 5 reviews in a grid
4. FAQ: 4 questions, collapsed accordion
5. Final CTA: same as hero
```

**Spell out copy and placement when it matters.** "Add an email capture somewhere" leaves Replo guessing on three things; "email field under the hero, button text 'Get 15% Off'" leaves it guessing on none.

**Let Replo explore first.** Before a redesign, ask "what would you improve on this page and why?" and pick from its answers.

## What's next

<CardGroup cols={3}>
  <Card title="Prompt Library" icon="book" href="/prompt-engineering/prompt-library">
    Ready-to-run prompts for launches, sales, listicles, and more.
  </Card>

  <Card title="Prompting Principles" icon="lightbulb" href="/prompt-engineering/prompting-principles">
    The three habits behind every good prompt.
  </Card>

  <Card title="Prompting Replo" icon="wand-magic-sparkles" href="/prompt-engineering/prompting-replo">
    Replo-specific moves: reference images, URL rebuilds, and recovering from mistakes.
  </Card>
</CardGroup>
