Head Management

HadarsHead controls <title>, <meta>, <link>, <script>, and <style> tags on both server and client without duplication.

Usage

Place HadarsHead anywhere in the component tree — no wrapper required. On the server it collects tags into the rendered HTML <head>. On the client it upserts them into document.head.

import { HadarsHead } from 'hadars';

const Page = () => (
    <>
        <HadarsHead status={200}>
            <title>My page</title>
            <meta name="description" content="A great page" />
            <meta property="og:title" content="My page" />
            <meta property="og:image" content="https://example.com/og.png" />
            <meta httpEquiv="content-language" content="en" />
            <link rel="canonical" href="https://example.com/page" />
            <link rel="stylesheet" href="/styles/page.css" />
            <link rel="preload" href="/fonts/inter.woff2" as="font" crossOrigin="anonymous" />
            <style data-id="page-critical">{criticalCSS}</style>
            <script src="/vendor/analytics.js" async />
            <script data-id="inline-config" dangerouslySetInnerHTML={{ __html: 'var X=1' }} />
        </HadarsHead>
        ...
    </>
);

The optional status prop sets the HTTP response status code for that render. It only takes effect on the server — the last HadarsHead with a status prop wins.

Deduplication

Each element type has a natural dedup key derived from its identifying attributes. Rendering the same HadarsHead block in multiple components or across re-renders will not produce duplicate tags — the existing element is found and updated in place.

ElementDedup keyNotes
<title>singularAlways one title per page — last write wins.
<meta name>name valuee.g. name="description" — one per name.
<meta property>property valuee.g. Open Graph tags like og:title.
<meta httpEquiv>http-equiv valueSupports both httpEquiv and http-equiv casing.
<meta charSet>singularOne charset per page.
<link>rel + href (+ as)Unique per URL. Without href, keyed by rel alone (e.g. preconnect).
<script src>src URLUnique per source URL.
<script data-id>data-id valueRequired for inline scripts — see below.
<style data-id>data-id valueRequired for inline styles — see below.

data-id for inline tags

Inline <script> (without src) and <style> elements have no natural URL to key on. Provide a data-id prop so hadars can find and update the same element across re-renders rather than appending a duplicate:

<HadarsHead>
    {/* Critical CSS injected by your CSS-in-JS or build tool */}
    <style data-id="critical-css">{criticalStyles}</style>

    {/* Analytics or config snippet */}
    <script
        data-id="gtm-config"
        dangerouslySetInnerHTML={{ __html: gtmSnippet }}
    />
</HadarsHead>

Omitting data-id on inline elements triggers a console warning at render time and falls back to append-only behaviour — safe for one-time static tags, but not for anything that re-renders or appears in multiple route components.

useId() compatibility

hadars's SSR renderer (slim-react) generates React.useId() values that match what React produces on the client. The IDs below were produced on the server and must survive hydration without warnings.

Single useId
_R_9du_
Multiple calls
_R_adu_
_R_aduH1_

Open the browser console — no hydration mismatch warnings means slim-react and React agree on every ID.