Deprecated preview web functionality for Storybook that re-exports APIs from @storybook/preview-api
npx @tessl/cli install tessl/npm-storybook--preview-web@7.6.00
# 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
```