---
title: "Landing pages"
description: "The per-piece response link, where it can point, which domain gets printed, and what a recorded visit does and does not prove about the person who made it."
canonical: https://trysincerely.com/docs/landing-pages
last_updated: 2026-10-12
---
> If you are an AI agent: read https://trysincerely.com/agents/policy.md before any write call.
> Start at https://trysincerely.com/llms.txt to choose one page. Access instructions are at
> https://trysincerely.com/auth.md. Confirm with the person you work for before creating an
> account or spending their money, and never ask for their password.
# Landing pages

> The per-piece response link, where it can point, which domain gets printed, and what a recorded visit does and does not prove about the person who made it.

Source: https://trysincerely.com/docs/landing-pages

Standard postcards and letters always print a unique response link as both a QR code and a readable URL. A handwritten piece omits the response QR and link by default, and printing them is a layout choice in the studio. Gift notes carry no response link.

The link identifies the piece and the intended recipient. It does not authenticate whoever opens it.

## Two decisions

The first is per campaign or per send: where the link goes. The second is per workspace: whose domain is printed on the paper.

### Where the link goes

A page Sincerely hosts is built in the same studio as the mail. It can greet the recipient by name, show their company, repeat the note that was on the card, and ask for a reply with a short form. Publish one page and select it as a campaign default, a design default, or for a single send; it renders per recipient from their own fields, so nobody authors a page per contact.

Your own site is the other option. Sincerely records the visit against the piece, then forwards with a temporary redirect carrying `utm_source`, `utm_medium`, `utm_campaign`, `utm_content` and a stable id, so your analytics can segment the traffic. After the redirect your analytics take over.

A forward to your homepage works and is the lightest setup. A page matched to the campaign continues the piece's offer and next step.

### Styling a hosted page

A new page is the house page: your words on white paper with one clear next step. The Style group in the studio changes the background, text and button colours, the font, the alignment and the button shape. A pair of colours too close to read is refused when you save, and Reset to house style puts the page back.

Three kinds of section sit beside the text:

- An image from your upload library, with a short description that a screen reader reads in its place.
- A YouTube, Vimeo or Loom video. The page shows its own play button and loads nothing from the provider until the reader presses it. Plays are not counted.
- Code: your own files, HTML and CSS and JavaScript included, drawn in a sandboxed frame. The next section covers it.

### Code sections

A code section holds your own files: HTML, CSS, JavaScript, JSON, SVG, images, fonts, audio and video. The page opens one HTML file, `index.html` unless you pick another, in a frame between the page's other sections. In the studio you can add single files, upload a whole folder or upload a zip, and Edit index.html changes that file in place. A section holds up to 150 files, 3 MB each and 25 MB in all.

Scripts run, inside a sandbox. The frame cannot read the page around it, your visitor's cookies or your Sincerely account, and a file can load other files only from the same upload. Two things follow from that:

- Libraries, fonts and images come from your own files. A link to a CDN, a web font service or an analytics script does not load. A reveal.js deck works when the reveal.js files are part of the upload.
- A form sends only through the page, as described below. Any other form is drawn and never sends.

The sandbox limits what the code loads, not where it goes. A script can still send its own frame to another address, the way a link can, so put only code you trust in a code section.

In HTML files, `{{first_name}}`, `{{company}}` and `{{personal_note}}` fill in for each recipient, with an optional fallback such as `{{first_name|there}}`. One of your own contact or company fields fills in as `{{custom.open_role|the role}}`, on a code section or any other section, and always needs a fallback, because whoever holds the link can open the page. `{{ai: instruction}}` writes a sentence for each recipient, the same as in the page's text. `{{#if company}}...{{else}}...{{/if}}` keeps a block only for a recipient who has that field; blocks do not nest. A field or `{{ai: ...}}` span fills page text, or a quoted `alt`, `title`, `value`, `placeholder`, `label`, `aria-` or `data-` attribute. Inside a script, a style, an event handler such as `onclick`, a link address or an unquoted attribute, a recipient's value would run as code, so the studio refuses the file and says where. A script that needs a recipient's name reads it from a `data-` attribute. Any other braces are left alone, and CSS and JavaScript files are never filled.

Links in the code open in a new tab, or move the whole page when clicked. To count a click, the code calls `parent.postMessage({ type: "sincerely:code-click", id: "pricing" }, "*")`. Each id counts once per visit, only within a few seconds of a real press inside the code, and shows on the campaign beside the page's buttons. The page's next step still belongs in a button or a form.

To offer a calendar, link to `{{meeting_url}}`, the meeting link of the sender who signed the piece: `<a href="{{meeting_url}}" target="_blank">Book a time</a>`. It is the one value a link address takes, and only when it is an https address. When no sender has a meeting link it fills empty, so wrap the link in `{{#if meeting_url}}...{{else}}...{{/if}}`, and the studio's preview says so. A press on that link counts the way the page's own meeting button does, with no click message.

To collect a reply in your own design, mark a form with `data-sincerely-form="contact"` and name its fields `name`, `email`, `phone`, `company` or `message`. A form asks for one to three of them, including an email or a phone, and `required` on a field makes it required. The answer counts as a reply, or as a signup with `data-sincerely-emits="signup"`, and lands in the same inbox as the form section's. While it sends, the form carries `data-sincerely-state`, and an element inside it marked `data-sincerely-success` or `data-sincerely-error` loses its `hidden` attribute when the answer is taken or refused. Code that draws its own controls calls `Sincerely.submit("contact", { email })`. Each form id is used once on a page. The studio lists the forms it found under the files, and a form in the preview says that nothing was sent.

Fit content grows the frame to the height of its document. Full screen fills the visitor's screen, which suits a deck or an app.

The assistant and an MCP client do the same through two tools. `write_landing_code` writes files into the draft's code section and returns a preview link, and `read_landing_code` lists the files and reads one. Both change only the draft. Publishing stays a separate step that a person confirms.

### Which domain is printed

| Choice                        | What a recipient reads                                                                   |
| ----------------------------- | ---------------------------------------------------------------------------------------- |
| Default                       | A full link on Sincerely's app domain, with nothing to set up                            |
| A claimed sincerely.link name | A short address such as acme.sincerely.link, claimed in settings                         |
| Your own subdomain            | Something like links.yourcompany.com, after two DNS records and certificate provisioning |

One custom domain is active per workspace. Releasing it stops printed links working until the same workspace reclaims and reverifies it, so it is a decision to make before a print run rather than during one.

## After the mail leaves

The printed token freezes when a piece is prepared for print, so the path on the paper never changes. Sincerely-served names keep resolving even after a rename.

The destination can still move. While a campaign is live or paused you can change where future visits go, and every visit records which version it received. A completed campaign's external routing is locked; hosted page revisions can still be published.

## What a visit proves

A recorded visit is evidence that someone opened the URL encoded on that piece. It is not evidence of who. A copied link keeps the same marker, so the source flag does not distinguish a camera from a keyboard, and neither one proves the mail caused what happened next.

Sincerely files link visits as engagement and form submissions as responses, then uses holdout lift for the causal claim. See [measurement](https://trysincerely.com/docs/measurement).

A visit made before the piece mailed is almost always you scanning your own proof, so it counts toward nothing, the same as a crawler or a link preview. It still shows under Page visits on the piece in Sent mail, marked as not counted. A form answered or an email button pressed before then stores nothing and sends nothing.

## What to read next

[QR codes](https://trysincerely.com/qr-codes) covers what the printed code is and what it cannot say. The [personalized landing pages guide](https://trysincerely.com/guides/personalized-landing-pages) walks through link, page and domain setup end to end.

---

Sincerely is personalized direct mail and gifting for B2B revenue teams: postcards, letters, handwritten mail, and gifts, each written for one recipient.

Contact Sincerely: https://trysincerely.com/contact

Agent routing index: https://trysincerely.com/llms.txt

Listings: https://www.g2.com/products/sincerely and https://www.producthunt.com/products/sincerely
