Freeform Landing Page Template

View as Markdown
Last updated July 17, 2026

A complete walkthrough for the most common Freeform use case: a campaign landing template that assembles content from several entries and a dynamic query, with no single connected content type behind it.

You'll build:

  • A Freeform template at /campaigns/spring-2026
  • One Pinned Entry providing the template-level hero
  • One Pinned Query pulling the current top 3 products
  • Reusable sections binding to both sources
  • Lives at a real route on your site

Prerequisite: Enable Freeform Feature is on in your Studio project (Enabling Freeform). If you haven't enabled it, do that first: the Design and Data tabs both disappear without it, so the Additional Entry Data / Queries sections you'll need below are unreachable.

The Setup

Two existing content types in your stack:

Click to enlarge

A campaign entry exists with a hero ready to go. Multiple product entries exist; some have featured: true.

Step 1: Create the Freeform Template

  1. Compositions → Templates tab → + New Template
  2. In the create dialog, pick Freeform (not "Connected Template")
  3. Name it spring_2026_campaign

Studio opens a canvas with the FREEFORM MODE badge in the top bar and an empty canvas with onboarding helpers: "Add Components To Canvas · Pin Data".

Click to enlarge

Click to enlarge

Step 2: Set the URL

Click the URL editor (pencil icon in the canvas toolbar). The Edit URL modal opens with the default Freeform pattern:

{{composition_uid}}

Replace it with a clean campaign URL:

/campaigns/spring-2026

Save. Studio reloads the iframe at the new path.

Click to enlarge

Detail: Freeform templates: URL pattern

Step 3: Pin the Campaign Entry

  1. Right panel → Data tab → Additional Entry Data section
  2. Click Link Entry
  3. In the search dialog, pick the campaign content type
  4. Search for "Spring 2026" → confirm

The pinned entry appears in the list. Studio gives it a binding handle you can use anywhere on the template.

Click to enlarge

Click to enlarge

Step 4: Pin the Products Query

  1. Data tab → Pinned Queries section
  2. Click Create Query
  3. Configure:
  4. Content type: product
  5. Filter: featured = true
  6. Order by: price ascending
  7. Limit: 3
  8. Save the pin

The query result is now bindable from any Repeater on the template.

Click to enlarge

Step 5: Add a Hero Section Bound to the Pinned Campaign

If you already have a landing_hero section (built in the overrides recipe), drop it. Otherwise build one inline:

  1. Drop a Box at the root → style as a hero
  2. Inside:
  3. Heading, bind text to Pinned Entry → Spring 2026 → headline
  4. Text, bind to Pinned Entry → Spring 2026 → subhead
  5. Image, bind src to Pinned Entry → Spring 2026 → hero_image
  6. Button, bind href to Pinned Entry → Spring 2026 → primary_cta

Studio's data picker shows pinned entries alongside template and other data sources.

Step 6: Add the Products Grid Bound to the Pinned Query

Below the hero:

  1. Drop a Heading, text: "Featured products"
  2. Drop a Box with a grid layout
  3. Inside the Box, drop a Repeater
  4. Bind the Repeater's source to Pinned Query → Featured Products
  5. Inside the Repeater, drop a Box (the card frame), and inside that:
  6. Image, bind to repeater.image (picker root: Repeater Data)
  7. Heading, bind to repeater.name
  8. Text, bind to repeater.price (your component can format it)
  9. Button, bind href to repeater.url

The Repeater iterates the query result; repeater.* (Repeater Data) refers to the current iteration item (a product entry). The SDK marks these as RepeaterBindingValue, distinct from template-level bindings.

Alternative: if you have a product_card section (built in the card-grid recipe) anchored on a product-shaped Global Field, drop it inside the Repeater instead. Studio scope-root matches it against the iteration item.

Step 7: Save and View

Save the composition.

Click to enlarge

Open http://localhost:3000/campaigns/spring-2026 in your browser.

You should see:

Click to enlarge

The hero is bound to the campaign entry. The grid auto-refreshes whenever the underlying products query result changes: publish a new featured product and it shows up here on next render.

What This Gives You

  • No new content type needed. You didn't model "campaign landing template" as a CT, you composed it from existing entries.
  • The query stays live. Marketing publishes a new featured product, and it appears on this template automatically.
  • One section can serve many templates. The card layout you built here works on any other Freeform or Connected template that pins products.
  • Per-template branding. This template can use one hero design; the next campaign uses a completely different layout, both Freeform, no shared CT constraint.

Common Patterns

One pinned entry for template metadata + N pinned queries for content. A campaign template pins the campaign entry (title, headline, theme image), plus queries for featured items, top stories, related links.

Multiple pinned entries assembled into one template. Pin a hero entry, a testimonial entry, and a CTA entry. Compose them into a single template where each section binds to its own pinned entry.

A "compare" template with two pinned entries side by side. Pin two products. Build a side-by-side layout. The same template works for any pair you swap in.

When Freeform Is NOT the Right Choice

SymptomBetter choice
Every campaign has the same structure with different contentBuild a campaign content type, use a Connected template
You're modelling repeating, content-driven templatesConnected template
The template is content-driven enough to deserve a CTConnected template
You'd be making the same Freeform composition over and overConnected template

Freeform is for genuinely one-off templates. If you find yourself copying a Freeform composition to make a similar one, that's a signal: make a content type instead.

See Also