---
title: 'useOf'
sidebar:
  order: 17
  title: useOf
---

The default blocks supplied by Storybook do not fit all use cases, so you might want to write your own blocks.

If your own doc blocks need to interface with annotations from Storybook—that is stories, meta or components—you can use the `useOf` hook. Pass in a module export of a story, meta, or component and it will return its annotated form (with applied parameters, args, loaders, decorators, play function) that you can then use for anything you like. In fact, most of the existing blocks like [`Description`](./doc-block-description.mdx) and [`Canvas`](./doc-block-canvas.mdx) use `useOf` under the hood.

Here’s an example of how the`useOf` hook could be used to create a custom block that displays the name of the story:

```jsx title=".storybook/blocks/StoryName.jsx"
import { useOf } from '@storybook/blocks';

/**
 * A block that displays the story name or title from the of prop
 * - if a story reference is passed, it renders the story name
 * - if a meta reference is passed, it renders the stories' title
 * - if nothing is passed, it defaults to the primary story
 */
export const StoryName = ({ of }) => {
  const resolvedOf = useOf(of || 'story', ['story', 'meta']);
  switch (resolvedOf.type) {
    case 'story': {
      return <h1>{resolvedOf.story.name}</h1>;
    }
    case 'meta': {
      return <h1>{resolvedOf.preparedMeta.title}</h1>;
    }
  }
  return null;
};
```

{/* prettier-ignore-start */}

```md title="ButtonDocs.mdx"
import { Meta } from '@storybook/blocks';
import { StoryName } from '../.storybook/blocks/StoryName';
import * as ButtonStories from './Button.stories';

<Meta of={ButtonStories} />

{/* Renders "Secondary" */}
<StoryName of={ButtonStories.Secondary} />

{/* Renders "Primary" */}
<StoryName />

{/* Renders "Button" */}
<StoryName of={ButtonStories} />
```

{/* prettier-ignore-end */}

## useOf

### Type

{/* prettier-ignore-start */}

```ts
(
  moduleExportOrType: ModuleExport | 'story' | 'meta' | 'component',
  validTypes?: Array<'story' | 'meta' | 'component'>
) => EnhancedResolvedModuleExportType
```

{/* prettier-ignore-end */}

### Parameters

#### `moduleExportOrType`

(**Required**)

Type: `ModuleExport | 'story' | 'meta' | 'component'`

Provides the story export, meta export, component export, or CSF file exports from which you get annotations.

When the custom block is in an [attached doc](./doc-block-meta.mdx#attached-vs-unattached), it’s also possible to get the primary (first) story, meta, or component by passing in a string instead. This is useful as a fallback, so the `of` prop can be omitted in your block. The most common pattern is using this as `useOf(props.of || 'story')` which will fall back to the primary story if no `of` prop is defined.

* `useOf('story')` returns the annotated primary story in attached mode; error in unattached mode
* `useOf('meta')` returns the annotated meta in attached mode; error in unattached mode
* `useOf('component')` returns the annotated component specified in the meta in attached mode; error in unattached mode

#### `validTypes`

Type: `Array<'story' | 'meta' | 'component'>`

Optionally specify an array of valid types that your block accepts. Passing anything other than the valid type(s) will result in an error. For example, the [`Canvas`](./doc-block-canvas.mdx) block uses `useOf(of, ['story'])`, which ensures it only accepts a reference to a story, not a meta or component.

### Return

The return value depends on the matched type:

#### `EnhancedResolvedModuleExportType['type'] === 'story'`

Type: `{ type: 'story', story: PreparedStory }`

For stories, annotated stories are returned as is. They are prepared, meaning that they are already merged with project and meta annotations.

#### `EnhancedResolvedModuleExportType['type'] === 'meta'`

Type: `{ type: 'meta', csfFile: CSFFile, preparedMeta: PreparedMeta }`

For meta, the parsed CSF file is returned, along with prepared annotated meta. That is, project annotations merged with meta annotations, but no story annotations.

#### `EnhancedResolvedModuleExportType['type'] === 'component'`

Type: `{ type: 'component', component: Component, projectAnnotations: NormalizedProjectAnnotations }`

For components, the component is returned along with project annotations; no meta or story annotations.

Note that it’s often impossible for the hook to determine if a component is passed in or any other object, so it behaves like an `unknown` type as well.
