Skip to content

CourseHeader

Generated from front/ui/catalogue/examples/CourseHeader.json

course · static (no JavaScript) · no children. All components: component playground.

Top of a course page: title, subtitle, facts, tutors, poster and the start button.

Rendered from the example props below with the real component. Theme: coffee · oncall · nightsky · gravity · poland · ulam · platform · open on its own

{
"component": "CourseHeader",
"props": {
"variant": "editorial",
"eyebrow": "Course",
"title": "Brewing basics",
"subtitle": "Extraction, grind and ratio.",
"summary": "Twelve short lessons that take you from a bad cup to a repeatable good one.",
"facts": [
{
"label": "Lessons",
"value": "12"
},
{
"label": "Level",
"value": "Beginner"
}
],
"image": {
"src": "/og-image.png",
"alt": "A pour-over coffee brewing on a scale",
"width": 1200,
"height": 630
},
"tutors": [
{
"name": "Ada Kowalska",
"role": "Head roaster",
"place": "Krakow",
"bio": "Fifteen years of roasting and teaching extraction."
}
],
"primaryCta": {
"label": "Start learning",
"href": "/learn/1"
},
"secondaryCta": {
"label": "Syllabus",
"href": "#syllabus"
},
"progress": 40
}
}
Prop Type Required Notes
variant "editorial" | "console" | "adventure" Layout. default "editorial"
eyebrow string Small label above the title. max length 80
title string yes Course title. max length 160
subtitle string Subtitle. max length 200
summary string Summary. max length 600
facts array of objects Facts (level, length, language…). max 6 items
facts[].label string yes Label. max length 40
facts[].value string yes Value. max length 60
facts[].note string Small note. max length 80
image object An image with explicit size (prevents layout shift)
image.src string (href) yes Image URL (local /images/… or the tenant storage). max length 2048
image.alt string yes Text alternative; empty string only for decorative images. max length 300
image.width integer yes Intrinsic width in px. ≥ 1
image.height integer yes Intrinsic height in px. ≥ 1
tutors array of objects Tutors. max 4 items
tutors[].name string yes Full name. max length 80
tutors[].role string Role or title. max length 80
tutors[].place string Place. max length 80
tutors[].bio string Short bio. max length 600
tutors[].image object An image with explicit size (prevents layout shift)
tutors[].image.src string (href) yes Image URL (local /images/… or the tenant storage). max length 2048
tutors[].image.alt string yes Text alternative; empty string only for decorative images. max length 300
tutors[].image.width integer yes Intrinsic width in px. ≥ 1
tutors[].image.height integer yes Intrinsic height in px. ≥ 1
primaryCta object A link or call to action
primaryCta.label string yes Visible text. max length 80
primaryCta.href string (href) yes Target URL. max length 2048
secondaryCta object A link or call to action
secondaryCta.label string yes Visible text. max length 80
secondaryCta.href string (href) yes Target URL. max length 2048
progress integer Learner completion 0–100; omit when unknown. ≥ 0, ≤ 100
id string Anchor id for in-page links (letters, digits, dashes). max length 40

What a text-only client, an unknown renderer or a plain-text channel shows for the example above.

Brewing basics
Extraction, grind and ratio.
Twelve short lessons that take you from a bad cup to a repeatable good one.

A node whose props fail the schema never breaks the page: the renderer shows the plain-text fallback instead (and logs the issues in development).

{
"subtitle": "No title"
}

Issues:

  • /title is required

Rendered as:

No title

axe-core: 27 rules passed, 0 violations, 0 need manual review. Run at build time on the server-rendered HTML in jsdom. Colour contrast and layout rules need a browser and are covered by the Playwright axe scans of the reference frontend.