Content, policy document
Install
npx shadcn add @klarhimmel/content-legalUsage
import { Theme } from '@/components/klarhimmel/theme/style';
import { BlockSurface } from '@/components/klarhimmel/blocks/surface';
import ContentLegal from '@/components/klarhimmel/blocks/content-legal';
export default function Section() {
return (
<Theme theme="brand">
<BlockSurface>
<ContentLegal props={{
"eyebrow": "Legal",
"title": "Privacy policy",
"updated": "Last updated 1 October 2026",
"intro": "This explains what Exempelhotellet collects when you book a stay, why, and how long we keep it. It is written to be read.",
"contentsLabel": "On this page",
"sections": [
{
"title": "What we collect",
"body": "Your name, email address and phone number, the dates of your stay, and the payment reference from our payment provider. We never see or store full card numbers."
},
{
"title": "Why we collect it",
"body": "To confirm your booking, to contact you if something changes, and to meet accounting and tax rules that require us to keep invoices."
},
{
"title": "How long we keep it",
"body": "Booking details for two years after your stay, invoices for seven years as the law requires. After that they are deleted automatically."
},
{
"title": "Who else sees it",
"body": "Our payment provider and our email service, both inside the EU and both bound by a data processing agreement. We never sell data."
},
{
"title": "Your rights",
"body": "You can ask to see, correct or delete what we hold about you at any time. Write to privacy@example.com and we answer within 30 days."
}
]
}} />
</BlockSurface>
</Theme>
);
}Install
Import
import Block from '@/components/klarhimmel/blocks/content-legal';- content/legal
- Category
- Long-form text and timelines for about and policy pages.
Notes
When to use it
A policy or terms page with a sticky contents list that jumps to numbered sections. For an ordinary article or about page without the contents list, `content-prose` is the simpler choice.
Writing for it
- Section titles are required and hold 80 characters. They become both the contents entries and the numbered h2 headings, so write them to make sense in a short list. - Each body holds 1200 characters in a single block of text, so split a long clause into its own section instead of cramming it in. - Fill the updated line (60 characters) with the date as the reader should see it, such as 'Last updated 3 March 2026'. The contents label (40 characters) is the small caption over the list.
Watch out for
The page title is drawn as the h1 here, not an h2, because a policy page usually has no hero. If a hero above it already carries the h1, set the headingLevel of this block to 2 so the page has only one.
Pairs well with
Usage
The block in a page, with its default content (long lists shortened). Every prop is in the table below.
import { Theme } from '@/components/klarhimmel/theme/style';
import { BlockSurface } from '@/components/klarhimmel/blocks/surface';
import ContentLegal from '@/components/klarhimmel/blocks/content-legal';
export default function Section() {
return (
<Theme theme="brand">
<BlockSurface>
<ContentLegal props={{
"eyebrow": "Legal",
"title": "Privacy policy",
"updated": "Last updated 1 October 2026",
"intro": "This explains what Exempelhotellet collects when you book a stay, why, and how long we keep it. It is written to be read.",
"contentsLabel": "On this page",
"sections": [
{
"title": "What we collect",
"body": "Your name, email address and phone number, the dates of your stay, and the payment reference from our payment provider. We never see or store full card numbers."
},
{
"title": "Why we collect it",
"body": "To confirm your booking, to contact you if something changes, and to meet accounting and tax rules that require us to keep invoices."
},
{
"title": "How long we keep it",
"body": "Booking details for two years after your stay, invoices for seven years as the law requires. After that they are deleted automatically."
},
{
"title": "Who else sees it",
"body": "Our payment provider and our email service, both inside the EU and both bound by a data processing agreement. We never sell data."
},
{
"title": "Your rights",
"body": "You can ask to see, correct or delete what we hold about you at any time. Write to privacy@example.com and we answer within 30 days."
}
]
}} />
</BlockSurface>
</Theme>
);
}Props
The type, default and text limit of every prop. On a real page, over-limit text is kept and checkSections flags it (Installation, Check a page before you ship); this live preview shows the default until it fits. The panel above edits all props.
| Prop | Type | Default | Description |
|---|---|---|---|
eyebrow | string | 'Legal' | Text, up to 60 characters. |
title | string | 'Privacy policy' | Text, up to 100 characters. |
updated | string | 'Last updated 1 October 2026' | Text, up to 60 characters. |
intro | string | 'This explains what Exempelhotellet …' | Text, up to 500 characters. |
contentsLabel | string | 'On this page' | Text, up to 40 characters. |
sections | { title, body }[] | 5 items | List of 2 to 8. Each item: title, body. |
headingLevel | '1' | '2' | - | One of '1', '2'. Optional; empty is not rendered. |