Freeform Landing Page Template
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:
A campaign entry exists with a hero ready to go. Multiple product entries exist; some have featured: true.
Step 1: Create the Freeform Template
- Compositions → Templates tab → + New Template
- In the create dialog, pick Freeform (not "Connected Template")
- 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".
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.
Detail: Freeform templates: URL pattern
Step 3: Pin the Campaign Entry
- Right panel → Data tab → Additional Entry Data section
- Click Link Entry
- In the search dialog, pick the campaign content type
- 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.
Step 4: Pin the Products Query
- Data tab → Pinned Queries section
- Click Create Query
- Configure:
- Content type: product
- Filter: featured = true
- Order by: price ascending
- Limit: 3
- Save the pin
The query result is now bindable from any Repeater on the template.
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:
- Drop a Box at the root → style as a hero
- Inside:
- Heading, bind text to Pinned Entry → Spring 2026 → headline
- Text, bind to Pinned Entry → Spring 2026 → subhead
- Image, bind src to Pinned Entry → Spring 2026 → hero_image
- 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:
- Drop a Heading, text: "Featured products"
- Drop a Box with a grid layout
- Inside the Box, drop a Repeater
- Bind the Repeater's source to Pinned Query → Featured Products
- Inside the Repeater, drop a Box (the card frame), and inside that:
- Image, bind to repeater.image (picker root: Repeater Data)
- Heading, bind to repeater.name
- Text, bind to repeater.price (your component can format it)
- 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.
Open http://localhost:3000/campaigns/spring-2026 in your browser.
You should see:
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
| Symptom | Better choice |
|---|---|
| Every campaign has the same structure with different content | Build a campaign content type, use a Connected template |
| You're modelling repeating, content-driven templates | Connected template |
| The template is content-driven enough to deserve a CT | Connected template |
| You'd be making the same Freeform composition over and over | Connected 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
- Freeform overview
- Pinned Entries
- Pinned Queries
- Card grid with slots: reuse the product grid pattern in Connected templates too