The marketing site header: a logo/brand mark, a center nav slot, an end slot (usually
login/signup), a dark mode toggle, and a built-in mobile hamburger menu. Place it as the first
thing on the page, before <Base>.
product"blogs"). Derives the default logo and fetches the cloud
updates banner on hyvor.com.instance"https://hyvor.com"name"HYVOR"subNamelogoproduct-derived default.darkToggletruemaxfalsemenuLabel"Menu"aria-label for the mobile hamburger menu button. Translate this when localizing the
page.logoAltText"Logo"name/subName are product-defined and stay as-is.centerHeaderNavLink. You can also use Dropdowns here (e.g. for a "Resources" menu).endOn mobile and tablets (<=992px), content in both center and end slots will be hidden, and a hamburger menu will be shown instead. The hamburger
menu opens a dropdown with the content of both slots (with a divider between them), and its icon switches
from a hamburger to a close (X) icon while open. Clicking any link inside the menu closes it automatically.
The header also gains a bottom border once the page is scrolled, so it stays visually separated from the content beneath it.
HeaderNavLink is a pill-shaped nav link meant to be used inside the center slot (and inside dropdown menus placed there). It renders an <a> when given an href, or a <span> otherwise, so it can also be used as a Dropdown trigger (e.g. a "Resources" link that opens a submenu).
hrefspan.activefalsemenufalsedescription is given.startdescription is given.childrenenddescription is given.description<script>
import Header from "@hyvor/design/marketing/Header.svelte";
import { HeaderNavLink } from "@hyvor/design/marketing";
import { Button, Dropdown } from "@hyvor/design/components";
import IconCaretDown from "@hyvor/icons/IconCaretDown";
import IconPalette from "@hyvor/icons/IconPalette";
import IconPuzzle from "@hyvor/icons/IconPuzzle";
import logo from '../img/logo.svg';
let resourcesOpen = $state(false);
</script>
<Header
logo={logo}
subName="Talk"
>
{#snippet center()}
<HeaderNavLink href="/docs" active={page.url.pathname.startsWith('/docs')}>
Docs
</HeaderNavLink>
<HeaderNavLink href="/pricing" active={page.url.pathname === '/pricing'}>
Pricing
</HeaderNavLink>
<Dropdown bind:show={resourcesOpen} contentPadding={8}>
{#snippet trigger()}
<HeaderNavLink active={resourcesOpen}>
Resources
{#snippet end()}
<IconCaretDown size={11} />
{/snippet}
</HeaderNavLink>
{/snippet}
{#snippet content()}
<HeaderNavLink href="/themes" active={page.url.pathname === '/themes'}>
{#snippet start()}<IconPalette size={15} />{/snippet}
Themes
{#snippet description()}Blog themes to match your brand{/snippet}
</HeaderNavLink>
<HeaderNavLink href="/integrations" active={page.url.pathname.startsWith('/integrations')}>
{#snippet start()}<IconPuzzle size={15} />{/snippet}
Integrations
{#snippet description()}Connect with your favorite tools{/snippet}
</HeaderNavLink>
{/snippet}
</Dropdown>
{/snippet}
{#snippet end()}
<div>
<Button as="a" href="/login" color="invisible">
Login
</Button>
<Button as="a" href="/signup">
Signup
</Button>
</div>
{/snippet}
</Header>HeaderLanguageToggle is for marketing sites that serve each language on its own URL
(e.g. a SvelteKit [[lang]] route param) rather than switching language client-side on
one page. Use it inside the center slot, next to your HeaderNavLinks. It's not related to InternationalizationService/LanguageToggle, which
swap translated strings in place on a single page; use that instead if you don't have per-language
routes. See it in action in the header of /test.
languages{ code, flag, name }.currenthref(code: string) => string. Returns the URL for switching to the given language
code. Build it however your routing works, e.g. with buildLocalizedUrl below.showNamefalsealign"center"Dropdown.position"bottom"Dropdown.label"Change language"aria-label for the trigger button. Translate this when localizing the page.A small helper for the common convention where the default language is served without a prefix and
every other language is served under /{code}:
buildLocalizedUrl(path: string, currentLang: string, targetLang: string, defaultLang: string): string
buildLocalizedUrl('/pricing', 'en', 'fr', 'en') // '/fr/pricing'
buildLocalizedUrl('/fr/pricing', 'fr', 'en', 'en') // '/pricing'
buildLocalizedUrl('/fr', 'fr', 'en', 'en') // '/'If your app routes languages differently (a subdomain per locale, a query param, ...), skip buildLocalizedUrl and build href yourself. HeaderLanguageToggle doesn't assume any particular URL scheme.
<script>
import { HeaderLanguageToggle, buildLocalizedUrl } from "@hyvor/design/marketing";
import { page } from '$app/stores';
const languages = [
{ code: 'en', flag: '🇬🇧', name: 'English' },
{ code: 'fr', flag: '🇫🇷', name: 'Français' }
];
const defaultLanguage = 'en';
const currentLang = $derived(
languages.find((l) => l.code === $page.url.pathname.split('/')[1])?.code ?? defaultLanguage
);
</script>
<Header product="blogs">
{#snippet center()}
<HeaderNavLink href="/pricing">Pricing</HeaderNavLink>
<HeaderNavLink href="/docs">Docs</HeaderNavLink>
<HeaderLanguageToggle
{languages}
current={currentLang}
href={(code) => buildLocalizedUrl($page.url.pathname, currentLang, code, defaultLanguage)}
/>
{/snippet}
</Header>