Personalize a landing page from a domain
Use brandRNA's brand pack to render a tailored landing page that mirrors the target's visual identity.
When a sales prospect lands on your site from an outbound email, generic copy and stock visuals waste the moment. With brandRNA you can fetch their brand identity from a domain in one HTTP call and render a landing page that looks like a continuation of their product — same colours, same fonts, same logo in your hero.
This recipe shows the end-to-end flow.
When this is useful
- Outbound landing pages — sales pages personalised to the prospect's brand at click-through time.
- Reverse-trial onboarding — show the new signup what their dashboard looks like with their own colours plugged in before they invite the team.
- Pitch decks / demo videos — script-driven reskins of a product walkthrough.
Prerequisites
- A brandRNA API key — see Quickstart if you don't
have one. Store it in
BRANDRNA_API_KEY(env var, never committed). - A landing-page rendering layer that can take colour + font tokens at request time. Tailwind is shown below; CSS variables work just as well.
Step-by-step
Fetch the brand pack
Hit the cached consolidated endpoint with the prospect's domain:
curl -H "Authorization: Bearer $BRANDRNA_API_KEY" \
https://api.brandrna.com/api/v1/pack/stripe.comimport os
import httpx
KEY = os.environ['BRANDRNA_API_KEY']
async def fetch_pack(domain: str) -> dict:
async with httpx.AsyncClient(timeout=30) as client:
r = await client.get(
f"https://api.brandrna.com/api/v1/pack/{domain}",
headers={"Authorization": f"Bearer {KEY}"},
)
r.raise_for_status()
return r.json()const KEY = process.env.BRANDRNA_API_KEY!;
export async function fetchPack(domain: string) {
const res = await fetch(
`https://api.brandrna.com/api/v1/pack/${domain}`,
{ headers: { Authorization: `Bearer ${KEY}` } },
);
if (!res.ok) throw new Error(`brandRNA ${res.status}`);
return res.json();
}Extract colours and fonts
The response is a flat document — pull what you need:
const pack = await fetchPack("stripe.com");
const tokens = {
colors: {
primary: pack.colors.primary, // "#635BFF"
secondary: pack.colors.secondary, // "#0A2540"
accent: pack.colors.accent, // "#00D4FF"
bg: pack.colors.background, // "#FFFFFF"
text: pack.colors.text, // "#0A2540"
},
font: pack.fonts[0]?.family ?? "Inter", // "sohne-var"
};Inject into the page at render time
For Tailwind-based stacks, see Use brand colours in a Tailwind config for a build-time approach. For request-time injection, write CSS variables into the page head:
export default async function LandingPage({ domain }: { domain: string }) {
const pack = await fetchPack(domain);
const c = pack.colors;
return (
<html>
<head>
<style>{`
:root {
--brand-primary: ${c.primary};
--brand-secondary: ${c.secondary};
--brand-bg: ${c.background};
--brand-text: ${c.text};
}
body { font-family: ${pack.fonts[0]?.family ?? "Inter"}, sans-serif; }
`}</style>
</head>
<body className="bg-[var(--brand-bg)] text-[var(--brand-text)]">
<Hero pack={pack} />
<Features pack={pack} />
</body>
</html>
);
}Use the canonical logo in the hero
The brand pack returns multiple logo variants. Use role: "wordmark"
where you have horizontal space, role: "icon" for tight slots:
const wordmark = pack.logos.find((l: any) => l.role === "wordmark");
const url = wordmark?.url; // hosted by brandRNA, no CORS issues
<img src={url} alt={`${pack.brand} logo`} className="h-10" />For dark backgrounds, prefer the dark variant:
const darkUrl = wordmark?.variants?.includes("dark")
? wordmark.url.replace(/\.svg$/, ".dark.svg")
: wordmark.url;Cache the pack server-side
A request-time fetch adds ~80ms latency on cache hits. For high-traffic landing pages, cache the pack in your own backend with the same 24h TTL brandRNA uses internally. See Cache brand packs in your own backend for the recommended schema and invalidation hooks.
Final result
A landing page that mirrors the prospect's brand without manual design work. Pair this with a copy-rewriter (LLM or template) keyed on the same domain to personalise the headline too.
Famous domains return instantly from cache (metadata.cached: true,
$0). Novel domains trigger a 5–15s extraction and count toward your
quota. Plan your timeouts accordingly.
What's next
- See Use brand colours in a Tailwind config for the build-time variant.
- For multi-tenant SaaS that personalises every page, see Cache brand packs in your own backend.
- The full BrandPack schema lives in the API reference.