or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# Storybook Preview Web

1

2

Storybook Preview Web is a deprecated facade package that provides web-specific preview functionality for Storybook. This package served as a compatibility layer during the transition to @storybook/preview-api and is scheduled for removal in Storybook 8.0.

3

4

**⚠️ Deprecation Notice**: This package is deprecated and will be removed in Storybook 8.0. Users should migrate to importing directly from `@storybook/preview-api`.

5

6

## Package Information

7

8

- **Package Name**: @storybook/preview-web

9

- **Package Type**: npm

10

- **Language**: TypeScript

11

- **Installation**: `npm install @storybook/preview-web`

12

- **Status**: Deprecated (scheduled for removal in v8.0)

13

14

## Core Imports

15

16

```typescript

17

import {

18

PreviewWeb,

19

DocsContext,

20

simulatePageLoad,

21

simulateDOMContentLoaded,

22

composeStory,

23

composeStories,

24

setProjectAnnotations

25

} from "@storybook/preview-web";

26

```

27

28

For CommonJS:

29

30

```javascript

31

const {

32

PreviewWeb,

33

DocsContext,

34

simulatePageLoad,

35

simulateDOMContentLoaded,

36

composeStory,

37

composeStories,

38

setProjectAnnotations

39

} = require("@storybook/preview-web");

40

```

41

42

## Basic Usage

43

44

```typescript

45

import {

46

PreviewWeb,

47

DocsContext,

48

simulatePageLoad,

49

simulateDOMContentLoaded,

50

composeStory

51

} from "@storybook/preview-web";

52

53

// Initialize preview web instance (sets up global __STORYBOOK_PREVIEW__)

54

const preview = new PreviewWeb();

55

56

// DocsContext is typically created internally by Storybook

57

// but shows the required constructor signature

58

const docsContext = new DocsContext(

59

channel,

60

store,

61

renderStoryToElement,

62

csfFiles

63

);

64

65

// Simulate page events for testing

66

simulatePageLoad(document.body);

67

simulateDOMContentLoaded();

68

69

// Compose story for testing

70

import * as ButtonStories from './Button.stories';

71

const Primary = composeStory(ButtonStories.Primary, ButtonStories.default);

72

const renderedStory = Primary({ label: 'Hello World' });

73

```

74

75

## Migration Guide

76

77

**From (deprecated):**

78

```typescript

79

import { PreviewWeb, DocsContext } from "@storybook/preview-web";

80

```

81

82

**To (recommended):**

83

```typescript

84

import { PreviewWeb, DocsContext } from "@storybook/preview-api";

85

```

86

87

## Capabilities

88

89

### Preview Management

90

91

Core preview functionality for managing Storybook's preview environment and story rendering.

92

93

```typescript { .api }

94

class Preview<TRenderer extends Renderer> {

95

constructor();

96

// Core preview functionality methods

97

}

98

99

class PreviewWithSelection<TFramework extends AnyFramework> extends Preview<TFramework> {

100

constructor();

101

// Selection and navigation functionality

102

}

103

104

class PreviewWeb<TFramework extends AnyFramework> extends PreviewWithSelection<TFramework> {

105

constructor();

106

// Web-specific preview implementation

107

// Sets up global __STORYBOOK_PREVIEW__ instance

108

}

109

```

110

111

### Documentation Context

112

113

Documentation context management for rendering stories in documentation mode.

114

115

```typescript { .api }

116

class DocsContext<TRenderer extends Renderer> {

117

constructor(

118

channel: Channel,

119

store: StoryStore<TRenderer>,

120

renderStoryToElement: DocsContextProps<TRenderer>['renderStoryToElement'],

121

csfFiles: CSFFile<TRenderer>[]

122

);

123

124

// Core documentation methods

125

referenceMeta(metaExports: ModuleExports, attach: boolean): void;

126

resolveOf<TType extends ResolvedModuleExportType>(

127

moduleExportOrType: ModuleExport | TType,

128

validTypes?: TType[]

129

): ResolvedModuleExportFromType<TType, TRenderer>;

130

storyIdByName(storyName: StoryName): StoryId;

131

storyById(id?: StoryId): PreparedStory<TRenderer>;

132

componentStories(): PreparedStory<TRenderer>[];

133

getStoryContext(story: PreparedStory<TRenderer>): StoryContextForLoaders<TRenderer>;

134

loadStory(id: StoryId): Promise<PreparedStory<TRenderer>>;

135

}

136

137

interface DocsContextProps<TRenderer extends Renderer> {

138

// Meta and story resolution

139

referenceMeta: (metaExports: ModuleExports, attach: boolean) => void;

140

resolveOf<TType extends ResolvedModuleExportType>(

141

moduleExportOrType: ModuleExport | TType,

142

validTypes?: TType[]

143

): ResolvedModuleExportFromType<TType, TRenderer>;

144

145

// Story lookup and access

146

storyIdByName: (storyName: StoryName) => StoryId;

147

storyById: (id?: StoryId) => PreparedStory<TRenderer>;

148

componentStories: () => PreparedStory<TRenderer>[];

149

150

// Story context and rendering

151

getStoryContext: (story: PreparedStory<TRenderer>) => StoryContextForLoaders<TRenderer>;

152

loadStory: (id: StoryId) => Promise<PreparedStory<TRenderer>>;

153

renderStoryToElement: (

154

story: PreparedStory<TRenderer>,

155

element: HTMLElement,

156

callbacks: RenderContextCallbacks<TRenderer>,

157

options: StoryRenderOptions

158

) => () => Promise<void>;

159

160

// Communication and configuration

161

channel: Channel;

162

projectAnnotations: NormalizedProjectAnnotations<TRenderer>;

163

}

164

165

type DocsRenderFunction<TRenderer extends Renderer> = (

166

docsContext: DocsContextProps<TRenderer>,

167

docsParameters: Parameters,

168

element: HTMLElement

169

) => Promise<void>;

170

171

interface RenderContextCallbacks<TRenderer extends Renderer> {

172

showMain: () => void;

173

showError: (error: { title: string; description: string }) => void;

174

showException: (err: Error) => void;

175

}

176

177

interface StoryRenderOptions {

178

autoplay?: boolean;

179

forceInitialArgs?: boolean;

180

}

181

```

182

183

### Page Simulation

184

185

Utilities for simulating browser events, primarily used for testing and initialization.

186

187

```typescript { .api }

188

/**

189

* Simulates a page load event by executing scripts in a container

190

* @param $container - The container element to process scripts from

191

*/

192

function simulatePageLoad($container: any): void;

193

194

/**

195

* Simulates a DOM content loaded event on the document

196

*/

197

function simulateDOMContentLoaded(): void;

198

```

199

200

### Testing Utilities

201

202

Functions for composing and testing individual stories in isolation, useful for unit testing components.

203

204

```typescript { .api }

205

/**

206

* Composes a single story for use in testing environments

207

* @param storyExport - The story export from a CSF file

208

* @param metaExport - The meta export from the same CSF file

209

* @param projectAnnotations - Global project configuration

210

* @returns Composed story function ready for testing

211

*/

212

function composeStory<TRenderer extends Renderer>(

213

storyExport: StoryAnnotation<TRenderer>,

214

metaExport: Meta<TRenderer>,

215

projectAnnotations?: ProjectAnnotations<TRenderer>

216

): ComposedStory<TRenderer>;

217

218

/**

219

* Composes all stories from a CSF module for testing

220

* @param csfExports - All exports from a CSF file

221

* @param projectAnnotations - Global project configuration

222

* @returns Object with all composed stories keyed by export name

223

*/

224

function composeStories<TRenderer extends Renderer>(

225

csfExports: ModuleExports,

226

projectAnnotations?: ProjectAnnotations<TRenderer>

227

): ComposedStoryModule<TRenderer>;

228

229

/**

230

* Sets global project annotations for story composition

231

* @param projectAnnotations - Global configuration to apply to all composed stories

232

*/

233

function setProjectAnnotations<TRenderer extends Renderer>(

234

projectAnnotations: ProjectAnnotations<TRenderer>

235

): void;

236

```

237

238

### Configuration Management

239

240

Legacy configuration composition functionality (marked for removal).

241

242

```typescript { .api }

243

/**

244

* Composes multiple configuration objects into project annotations

245

* @deprecated Marked for removal in 7.0, used for builder-vite compatibility

246

*/

247

function composeConfigs<TRenderer extends Renderer>(

248

moduleExportList: ModuleExports[]

249

): ProjectAnnotations<TRenderer>;

250

```

251

252

## Types

253

254

```typescript { .api }

255

/**

256

* Type alias for web-specific project annotations

257

*/

258

type WebProjectAnnotations = ProjectAnnotations;

259

260

/**

261

* Composed story ready for testing with args, parameters, and play functions

262

*/

263

interface ComposedStory<TRenderer extends Renderer> extends StoryFn<TRenderer> {

264

args: Args;

265

parameters: Parameters;

266

play?: (context: StoryContext<TRenderer>) => Promise<void> | void;

267

storyName: string;

268

}

269

270

/**

271

* Module containing all composed stories from a CSF file

272

*/

273

interface ComposedStoryModule<TRenderer extends Renderer> {

274

[storyName: string]: ComposedStory<TRenderer>;

275

}

276

277

/**

278

* Core story annotation with metadata

279

*/

280

interface StoryAnnotation<TRenderer extends Renderer> {

281

args?: Partial<Args>;

282

parameters?: Parameters;

283

decorators?: DecoratorFunction<TRenderer>[];

284

loaders?: LoaderFunction<TRenderer>[];

285

play?: (context: StoryContext<TRenderer>) => Promise<void> | void;

286

render?: StoryFn<TRenderer>;

287

name?: string;

288

}

289

290

/**

291

* Meta configuration for a CSF file

292

*/

293

interface Meta<TRenderer extends Renderer> {

294

title?: string;

295

component?: TRenderer['component'];

296

subcomponents?: Record<string, TRenderer['component']>;

297

args?: Partial<Args>;

298

argTypes?: ArgTypes;

299

parameters?: Parameters;

300

decorators?: DecoratorFunction<TRenderer>[];

301

loaders?: LoaderFunction<TRenderer>[];

302

render?: StoryFn<TRenderer>;

303

play?: (context: StoryContext<TRenderer>) => Promise<void> | void;

304

}

305

306

/**

307

* Prepared story with all enhancements applied

308

*/

309

interface PreparedStory<TRenderer extends Renderer> {

310

id: StoryId;

311

name: StoryName;

312

title: ComponentTitle;

313

kind: ComponentTitle;

314

story: StoryName;

315

parameters: Parameters;

316

initialArgs: Args;

317

argTypes: ArgTypes;

318

args: Args;

319

component: TRenderer['component'];

320

subcomponents: Record<string, TRenderer['component']>;

321

tags: Tag[];

322

globals: Globals;

323

moduleExport: ModuleExport;

324

originalStoryFn: StoryFn<TRenderer>;

325

undecoratedStoryFn: LegacyStoryFn<TRenderer>;

326

unboundStoryFn: LegacyStoryFn<TRenderer>;

327

applyLoaders: (context: StoryContextForLoaders<TRenderer>) => Promise<StoryContext<TRenderer>>;

328

playFunction?: (context: StoryContext<TRenderer>) => Promise<void> | void;

329

}

330

331

/**

332

* Story context for loaders phase

333

*/

334

interface StoryContextForLoaders<TRenderer extends Renderer> {

335

id: StoryId;

336

name: StoryName;

337

title: ComponentTitle;

338

kind: ComponentTitle;

339

story: StoryName;

340

parameters: Parameters;

341

initialArgs: Args;

342

argTypes: ArgTypes;

343

args: Args;

344

component: TRenderer['component'];

345

subcomponents: Record<string, TRenderer['component']>;

346

tags: Tag[];

347

globals: Globals;

348

viewMode: ViewMode;

349

}

350

351

/**

352

* Global log level configuration

353

*/

354

declare var LOGLEVEL: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent' | undefined;

355

```

356

357

## Architecture

358

359

This package uses a simple facade pattern:

360

361

- **Re-export Pattern**: All functionality is re-exported from `@storybook/preview-api/dist/preview-web`

362

- **Deprecation Warning**: Shows deprecation notice when imported using `@storybook/client-logger`

363

- **Compatibility Layer**: Maintains backward compatibility during ecosystem migration

364

- **Zero Implementation**: Contains no original implementation, only facade functionality

365

366

## Error Handling

367

368

The package itself doesn't throw specific errors, but re-exported functionality may throw:

369

370

### DocsContext Errors

371

- **`"Cannot attach a CSF file that has not been referenced"`**: When calling `attachCSFFile()` with an unreferenced CSF file

372

- **`"No primary story attached to this docs file"`**: When accessing primary story without using `<Meta of={} />`

373

- **`"No CSF file attached to this docs file"`**: When resolving meta or component without attached CSF file

374

- **`"No story found with that name: ${storyName}"`**: When calling `storyIdByName()` with non-existent story name

375

- **`"Called storyById for story that was never loaded: ${storyId}"`**: When accessing unloaded story by ID

376

377

### Composition Errors

378

- **Invalid story/meta exports**: When `composeStory` receives malformed CSF exports

379

- **Missing project annotations**: When required global configuration is not provided via `setProjectAnnotations`

380

381

### Preview Initialization Errors

382

- **Story index loading failures**: When Preview cannot fetch or parse story index

383

- **Module import failures**: When dynamic imports of story modules fail

384

- **Render function errors**: When story render functions throw during execution

385

386

### Common Solutions

387

```typescript

388

// Always check if DocsContext has required attachments

389

try {

390

const story = docsContext.storyById('example-story');

391

} catch (error) {

392

console.error('Story not found or not loaded:', error.message);

393

}

394

395

// Ensure project annotations are set before composing stories

396

import { setProjectAnnotations } from "@storybook/preview-web";

397

setProjectAnnotations(globalConfig);

398

```

399

400

## Common Use Cases

401

402

### Story Preview Setup

403

```typescript

404

import { PreviewWeb } from "@storybook/preview-web";

405

406

const preview = new PreviewWeb();

407

// Preview is automatically set up as global __STORYBOOK_PREVIEW__

408

```

409

410

### Documentation Context Creation

411

```typescript

412

import { DocsContext } from "@storybook/preview-web";

413

414

// Note: DocsContext requires channel, store, renderStoryToElement, and csfFiles

415

// This is typically created internally by Storybook

416

```

417

418

### Test Environment Setup

419

```typescript

420

import { simulatePageLoad, simulateDOMContentLoaded } from "@storybook/preview-web";

421

422

// In test setup

423

simulateDOMContentLoaded();

424

simulatePageLoad(document.body);

425

```

426

427

### Story Testing

428

```typescript

429

import { composeStory, composeStories } from "@storybook/preview-web";

430

import * as stories from "./Button.stories";

431

432

// Test individual story

433

const { Primary } = composeStories(stories);

434

test('renders primary button', () => {

435

const button = Primary();

436

expect(button).toBeTruthy();

437

});

438

439

// Or compose single story

440

const ComposedPrimary = composeStory(stories.Primary, stories.default);

441

test('renders composed story', () => {

442

const result = ComposedPrimary({ label: 'Test' });

443

expect(result).toBeTruthy();

444

});

445

```

446

447

## Dependencies

448

449

- **@storybook/client-logger**: Used for deprecation warnings

450

- **@storybook/preview-api**: Source of all re-exported functionality

451

452

## Package Configuration

453

454

```json

455

{

456

"main": "dist/entry.js",

457

"module": "dist/entry.mjs",

458

"types": "dist/entry.d.ts",

459

"exports": {

460

".": {

461

"types": "./dist/entry.d.ts",

462

"require": "./dist/entry.js",

463

"import": "./dist/entry.mjs"

464

}

465

}

466

}

467

```