# useDocumentClass (https://docs.salla.dev/twilight/react/hooks/use-document-class)



Use `useDocumentClass` when a page needs a class or attribute on `<html>` or `<body>`, such as `page-product` for your CSS, a `data-theme`, or `dir`. React cannot reach those elements from inside a component, and this hook also works while the server renders the page.

## Example [#example]

```tsx title="app/components/product/ProductShell.tsx"
import { useDocumentClass } from '@salla.sa/twilight-theme-engine/hooks/useDocumentClass';

export function ProductShell({ children }: { children: React.ReactNode }) {
  useDocumentClass({
    body: { class: ['page-product', 'has-sticky-bar'], 'data-page': 'product' },
    html: { 'data-layout': 'detail' },
  });
  return <main>{children}</main>;
}
```

## API [#api]

```ts
function useDocumentClass(descriptor: { body?: Attrs; html?: Attrs }): void;
```

`Attrs` is an object of attribute names and string values. `class` can also be an array of class names.

| Key    | Type    | Description              |
| ------ | ------- | ------------------------ |
| `body` | `Attrs` | Attributes for `<body>`. |
| `html` | `Attrs` | Attributes for `<html>`. |

How values combine when several components or nested routes set them:

* **`class`** is merged. Every active page's classes are added together, with duplicates removed.
* **Any other attribute** follows the deepest page: the most nested route's value wins.

Attributes are removed again when the component unmounts, so leaving a page removes its classes.

## useHostAttributes [#usehostattributes]

For attributes on **one element you render**, use `useHostAttributes`. It returns a ref callback. `true` sets an empty attribute, and `false`, `null` or `undefined` removes it.

```tsx title="app/components/common/Panel.tsx"
import { useHostAttributes } from '@salla.sa/twilight-theme-engine/hooks/useHostAttributes';

export function Panel({ open }: { open: boolean }) {
  const ref = useHostAttributes<HTMLDivElement>({ 'data-open': open, hidden: !open });
  return <div ref={ref}>...</div>;
}
```

## Gotchas [#gotchas]

* Pass the same shape each render. The hook compares the content, so a new object with the same values does not re-run it.
* The hook only changes attributes. To change what a page contains, render different JSX.
* For language and direction, see [Languages and RTL](https://docs.salla.dev/twilight/react/guide/languages-and-rtl) before setting `lang` or `dir` yourself.

## Next [#next]

* [Styling](https://docs.salla.dev/twilight/react/guide/styling) shows how to target these classes in your CSS.
* [Layouts](https://docs.salla.dev/twilight/react/layouts) shows where page frames set their own classes.
