Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
50a69cb
Enhance telemetry functionality by adding share-related events and up…
ndelangen Feb 4, 2026
6ebe665
Merge branch 'next' into norbert/share-channel-events
ndelangen Feb 4, 2026
73d6fb1
Refactor telemetry channel initialization by removing unnecessary opt…
ndelangen Feb 4, 2026
4ea4729
Init: Add telemetry event type exit
valentinpalkovic Feb 4, 2026
3fc04d3
Merge branch 'next' into valentin/add-exit-telemetry
valentinpalkovic Feb 5, 2026
26be096
fixes
ndelangen Feb 5, 2026
d5cc36a
Merge branch 'next' into norbert/share-channel-events
ndelangen Feb 5, 2026
a2b16c2
Update CHANGELOG.md for v10.2.7 [skip ci]
storybook-bot Feb 5, 2026
dff9167
Initial plan
Copilot Feb 5, 2026
0158973
Add expo to metaFrameworks telemetry
Copilot Feb 5, 2026
a2d5e71
fix: export interface declaration for NextPreview
icopp Feb 5, 2026
dfb8135
Merge pull request #33785 from icopp/patch-5
valentinpalkovic Feb 6, 2026
5175dce
Merge pull request #33783 from storybookjs/copilot/add-expo-telemetry…
valentinpalkovic Feb 6, 2026
5e1084c
Merge pull request #33773 from storybookjs/valentin/add-exit-telemetry
valentinpalkovic Feb 6, 2026
ce42f59
Merge pull request #33766 from storybookjs/norbert/share-channel-events
ndelangen Feb 6, 2026
a0c5494
Test: Update event creation logic in user-event package
valentinpalkovic Feb 6, 2026
735201a
Update yarn.lock
valentinpalkovic Feb 6, 2026
a4a0dff
Merge pull request #33787 from storybookjs/valentin/fix-event-view-un…
valentinpalkovic Feb 9, 2026
7ae6c20
Write changelog for 10.3.0-alpha.5 [skip ci]
storybook-bot Feb 9, 2026
51b9983
Merge branch 'next-release' into version-non-patch-from-10.3.0-alpha.4
valentinpalkovic Feb 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 10.2.7

- CSF: Fix cross-file story imports in csf-factories codemod - [#33723](https://github.com/storybookjs/storybook/pull/33723), thanks @yatishgoel!
- Core: Fix rendering of View Transitions in Firefox - [#33651](https://github.com/storybookjs/storybook/pull/33651), thanks @ghengeveld!
- Globals: Repair dynamicTitle: false for user-defined tools - [#33284](https://github.com/storybookjs/storybook/pull/33284), thanks @ia319!
- Logger: Honor --loglevel for npmlog output - [#33776](https://github.com/storybookjs/storybook/pull/33776), thanks @LouisLau-art!

## 10.2.6

- Addon-Vitest: Skip postinstall setup when configured - [#33712](https://github.com/storybookjs/storybook/pull/33712), thanks @valentinpalkovic!
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.prerelease.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
- Core: Ignore empty files when indexing - [#33782](https://github.com/storybookjs/storybook/pull/33782), thanks @JReinhold!
- Globals: Repair dynamicTitle: false for user-defined tools - [#33284](https://github.com/storybookjs/storybook/pull/33284), thanks @ia319!
- Logger: Honor --loglevel for npmlog output - [#33776](https://github.com/storybookjs/storybook/pull/33776), thanks @LouisLau-art!
- Telemetry: Add Expo metaframework - [#33783](https://github.com/storybookjs/storybook/pull/33783), thanks @copilot-swe-agent!
- Telemetry: Add init exit event - [#33773](https://github.com/storybookjs/storybook/pull/33773), thanks @valentinpalkovic!
- Telemetry: Add share events - [#33766](https://github.com/storybookjs/storybook/pull/33766), thanks @ndelangen!
- Test: Update event creation logic in user-event package - [#33787](https://github.com/storybookjs/storybook/pull/33787), thanks @valentinpalkovic!

## 10.3.0-alpha.4

Expand Down
5 changes: 2 additions & 3 deletions code/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,9 @@ module.exports = {
'import-x/no-named-as-default-member': 'warn',
'react/destructuring-assignment': 'warn',

// This warns about importing interfaces and types in a normal import, it's arguably better to import with the `type` prefix separate from the runtime imports,
// I leave this as a warning right now because we haven't really decided yet, and the codebase is riddled with errors if I set to 'error'.
// Our codebase is mostly TypeScript, and typescript will warn when imports are not found.
// It IS set to 'error' for JS files.
'import-x/named': 'warn',
'import-x/named': 'off',
},
},
{
Expand Down
7 changes: 7 additions & 0 deletions code/core/src/core-events/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ enum events {
OPEN_IN_EDITOR_RESPONSE = 'openInEditorResponse',
// Emitted when the manager UI sets up a focus trap
MANAGER_INERT_ATTRIBUTE_CHANGED = 'managerInertAttributeChanged',

SHARE_STORY_LINK = 'shareStoryLink',
SHARE_ISOLATE_MODE = 'shareIsolateMode',
SHARE_POPOVER_OPENED = 'sharePopoverOpened',
}

// Enables: `import Events from ...`
Expand Down Expand Up @@ -167,6 +171,9 @@ export const {
OPEN_IN_EDITOR_REQUEST,
OPEN_IN_EDITOR_RESPONSE,
MANAGER_INERT_ATTRIBUTE_CHANGED,
SHARE_STORY_LINK,
SHARE_ISOLATE_MODE,
SHARE_POPOVER_OPENED,
} = events;

export * from './data/create-new-story';
Expand Down
4 changes: 2 additions & 2 deletions code/core/src/core-server/presets/common-preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { initCreateNewStoryChannel } from '../server-channel/create-new-story-ch
import { initFileSearchChannel } from '../server-channel/file-search-channel';
import { initGhostStoriesChannel } from '../server-channel/ghost-stories-channel';
import { initOpenInEditorChannel } from '../server-channel/open-in-editor-channel';
import { initPreviewInitializedChannel } from '../server-channel/preview-initialized-channel';
import { initTelemetryChannel } from '../server-channel/telemetry-channel';
import { initializeChecklist } from '../utils/checklist';
import { defaultFavicon, defaultStaticDirs } from '../utils/constants';
import { initializeSaveStory } from '../utils/save-story/save-story';
Expand Down Expand Up @@ -271,7 +271,7 @@ export const experimental_serverChannel = async (
initCreateNewStoryChannel(channel, options, coreOptions);
initGhostStoriesChannel(channel, options, coreOptions);
initOpenInEditorChannel(channel, options, coreOptions);
initPreviewInitializedChannel(channel, options, coreOptions);
initTelemetryChannel(channel, options);

return channel;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';

import { makePayload } from './preview-initialized-channel';
import { makePayload } from './telemetry-channel';

describe('makePayload', () => {
beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import type { Channel } from 'storybook/internal/channels';
import { PREVIEW_INITIALIZED } from 'storybook/internal/core-events';
import {
PREVIEW_INITIALIZED,
SHARE_ISOLATE_MODE,
SHARE_POPOVER_OPENED,
SHARE_STORY_LINK,
} from 'storybook/internal/core-events';
import { type InitPayload, telemetry } from 'storybook/internal/telemetry';
import { type CacheEntry, getLastEvents } from 'storybook/internal/telemetry';
import { getSessionId } from 'storybook/internal/telemetry';
import type { CoreConfig, Options } from 'storybook/internal/types';
import type { Options } from 'storybook/internal/types';

export const makePayload = (
userAgent: string,
Expand All @@ -24,13 +29,9 @@ export const makePayload = (
return payload;
};

export function initPreviewInitializedChannel(
channel: Channel,
options: Options,
_coreConfig: CoreConfig
) {
channel.on(PREVIEW_INITIALIZED, async ({ userAgent }) => {
if (!options.disableTelemetry) {
export function initTelemetryChannel(channel: Channel, options: Options) {
if (!options.disableTelemetry) {
channel.on(PREVIEW_INITIALIZED, async ({ userAgent }) => {
try {
const sessionId = await getSessionId();
const lastEvents = await getLastEvents();
Expand All @@ -40,9 +41,16 @@ export function initPreviewInitializedChannel(
const payload = makePayload(userAgent, lastInit, sessionId);
telemetry('preview-first-load', payload);
}
} catch (e) {
// do nothing
}
}
});
} catch {}
});
channel.on(SHARE_POPOVER_OPENED, async () => {
telemetry('share', { action: 'popover-opened' });
});
channel.on(SHARE_STORY_LINK, async () => {
telemetry('share', { action: 'story-link-copied' });
});
channel.on(SHARE_ISOLATE_MODE, async () => {
telemetry('share', { action: 'isolate-mode-opened' });
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { global } from '@storybook/global';
import type { StoryObj } from '@storybook/react-vite';

import { ManagerContext } from 'storybook/manager-api';
import { expect, screen, waitFor } from 'storybook/test';
import { expect, fn, screen, waitFor } from 'storybook/test';

import { shareTool } from './share';

Expand All @@ -15,6 +15,7 @@ const managerContext = {
refId: undefined,
},
api: {
emit: fn().mockName('api::emit'),
getShortcutKeys: () => ({
copyStoryLink: ['alt', 'shift', 'l'],
openInIsolation: ['alt', 'shift', 'i'],
Expand Down
15 changes: 14 additions & 1 deletion code/core/src/manager/components/preview/tools/share.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import React, { useMemo, useState } from 'react';
import React, { useEffect, useMemo, useState } from 'react';

import { Button, PopoverProvider, TooltipLinkList } from 'storybook/internal/components';
import {
SHARE_ISOLATE_MODE,
SHARE_POPOVER_OPENED,
SHARE_STORY_LINK,
} from 'storybook/internal/core-events';
import type { Addon_BaseType } from 'storybook/internal/types';

import { global } from '@storybook/global';
Expand Down Expand Up @@ -71,6 +76,10 @@ const ShareMenu = React.memo(function ShareMenu({
const copyStoryLink = shortcutKeys?.copyStoryLink;
const openInIsolation = shortcutKeys?.openInIsolation;

useEffect(() => {
api.emit(SHARE_POPOVER_OPENED);
}, [api]);

const links = useMemo(() => {
const copyTitle = copied ? 'Copied!' : 'Copy story link';
const originHrefs = api.getStoryHrefs(storyId, { base: 'origin', refId });
Expand All @@ -84,6 +93,7 @@ const ShareMenu = React.memo(function ShareMenu({
icon: <LinkIcon />,
right: enableShortcuts ? <Shortcut keys={copyStoryLink} /> : null,
onClick: () => {
api.emit(SHARE_STORY_LINK, originHrefs.managerHref);
copy(originHrefs.managerHref);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
Expand All @@ -94,6 +104,9 @@ const ShareMenu = React.memo(function ShareMenu({
title: 'Open in isolation mode',
icon: <ShareAltIcon />,
right: enableShortcuts ? <Shortcut keys={openInIsolation} /> : null,
onClick: () => {
api.emit(SHARE_ISOLATE_MODE, originHrefs.previewHref);
},
href: originHrefs.previewHref,
target: '_blank',
rel: 'noopener noreferrer',
Expand Down
3 changes: 3 additions & 0 deletions code/core/src/manager/globals/exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,9 @@ export default {
'SET_WHATS_NEW_CACHE',
'SHARED_STATE_CHANGED',
'SHARED_STATE_SET',
'SHARE_ISOLATE_MODE',
'SHARE_POPOVER_OPENED',
'SHARE_STORY_LINK',
'STORIES_COLLAPSE_ALL',
'STORIES_EXPAND_ALL',
'STORY_ARGS_UPDATED',
Expand Down
1 change: 1 addition & 0 deletions code/core/src/telemetry/storybook-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export const metaFrameworks = {
'@tanstack/react-router': 'tanstack-react',
'@react-router/dev': 'react-router',
'@remix-run/dev': 'remix',
expo: 'expo',
} as Record<string, string>;

export const sanitizeAddonName = (name: string) => {
Expand Down
2 changes: 2 additions & 0 deletions code/core/src/telemetry/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export type EventType =
| 'scaffolded-empty'
| 'browser'
| 'canceled'
| 'exit'
| 'error'
| 'error-metadata'
| 'version-update'
Expand All @@ -42,6 +43,7 @@ export type EventType =
| 'migrate'
| 'preview-first-load'
| 'doctor'
| 'share'
| 'ghost-stories';
export interface Dependency {
version: string | undefined;
Expand Down
2 changes: 1 addition & 1 deletion code/frameworks/nextjs-vite/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ export function definePreview<Addons extends PreviewAddon<never>[]>(
});
}

interface NextPreview<T extends AddonTypes> extends ReactPreview<NextJsTypes & T> {}
export interface NextPreview<T extends AddonTypes> extends ReactPreview<NextJsTypes & T> {}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ProjectType } from 'storybook/internal/cli';
import type { JsPackageManager } from 'storybook/internal/common';
import { logger, prompt } from 'storybook/internal/node-logger';
import { telemetry } from 'storybook/internal/telemetry';
import type { SupportedLanguage } from 'storybook/internal/types';

import picocolors from 'picocolors';
Expand Down Expand Up @@ -91,6 +92,13 @@ We assume that Storybook is already instantiated for your project. Do you still
if (force || options.yes) {
options.force = true;
} else {
if (!options.disableTelemetry) {
await telemetry(
'exit',
{ eventType: 'init', reason: 'existing-installation' },
{ stripMetadata: true, immediate: true }
);
}
process.exit(0);
}
}
Expand Down
7 changes: 7 additions & 0 deletions code/lib/create-storybook/src/scaffold-new-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,13 @@ export const scaffoldNewProject = async (
}

if (projectStrategy === 'other') {
if (!disableTelemetry) {
await telemetry(
'exit',
{ eventType: 'init', reason: 'scaffold-other' },
{ stripMetadata: true, immediate: true }
);
}
logger.warn(
'To install Storybook on another framework, first generate a project with that framework and then rerun this command.'
);
Expand Down
3 changes: 2 additions & 1 deletion code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -220,5 +220,6 @@
"Dependency Upgrades"
]
]
}
},
"deferredNextVersion": "10.3.0-alpha.5"
}
2 changes: 1 addition & 1 deletion docs/versions/next.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"version":"10.3.0-alpha.5","info":{"plain":"- CLI: Support addon-vitest setup when --skip-install is passed - [#33718](https://github.com/storybookjs/storybook/pull/33718), thanks @valentinpalkovic!\n- CSF: Fix cross-file story imports in csf-factories codemod - [#33723](https://github.com/storybookjs/storybook/pull/33723), thanks @yatishgoel!\n- Core: Ignore empty files when indexing - [#33782](https://github.com/storybookjs/storybook/pull/33782), thanks @JReinhold!\n- Globals: Repair dynamicTitle: false for user-defined tools - [#33284](https://github.com/storybookjs/storybook/pull/33284), thanks @ia319!\n- Logger: Honor --loglevel for npmlog output - [#33776](https://github.com/storybookjs/storybook/pull/33776), thanks @LouisLau-art!"}}
{"version":"10.3.0-alpha.5","info":{"plain":"- CLI: Support addon-vitest setup when --skip-install is passed - [#33718](https://github.com/storybookjs/storybook/pull/33718), thanks @valentinpalkovic!\n- CSF: Fix cross-file story imports in csf-factories codemod - [#33723](https://github.com/storybookjs/storybook/pull/33723), thanks @yatishgoel!\n- Core: Ignore empty files when indexing - [#33782](https://github.com/storybookjs/storybook/pull/33782), thanks @JReinhold!\n- Globals: Repair dynamicTitle: false for user-defined tools - [#33284](https://github.com/storybookjs/storybook/pull/33284), thanks @ia319!\n- Logger: Honor --loglevel for npmlog output - [#33776](https://github.com/storybookjs/storybook/pull/33776), thanks @LouisLau-art!\n- Telemetry: Add Expo metaframework - [#33783](https://github.com/storybookjs/storybook/pull/33783), thanks @copilot-swe-agent!\n- Telemetry: Add init exit event - [#33773](https://github.com/storybookjs/storybook/pull/33773), thanks @valentinpalkovic!\n- Telemetry: Add share events - [#33766](https://github.com/storybookjs/storybook/pull/33766), thanks @ndelangen!\n- Test: Update event creation logic in user-event package - [#33787](https://github.com/storybookjs/storybook/pull/33787), thanks @valentinpalkovic!"}}
4 changes: 2 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8951,10 +8951,10 @@ __metadata:

"@testing-library/user-event@patch:@testing-library/user-event@npm%3A14.6.1#~/.yarn/patches/@testing-library-user-event-npm-14.6.1-5da7e1d4e2.patch":
version: 14.6.1
resolution: "@testing-library/user-event@patch:@testing-library/user-event@npm%3A14.6.1#~/.yarn/patches/@testing-library-user-event-npm-14.6.1-5da7e1d4e2.patch::version=14.6.1&hash=228211"
resolution: "@testing-library/user-event@patch:@testing-library/user-event@npm%3A14.6.1#~/.yarn/patches/@testing-library-user-event-npm-14.6.1-5da7e1d4e2.patch::version=14.6.1&hash=4faa83"
peerDependencies:
"@testing-library/dom": ">=7.21.4"
checksum: 10c0/837761d0a6f87268e0e4c69c1afaf14ddadea51aab44e82d22a12e1ae7c970f9af900b7d7379ed672132b76694c32f8cbd786020300261e805b499898b8f20f4
checksum: 10c0/b3d9c3351e7a3bb9169bd5262aaad7911647cf38d4f24d217561481a028fe3a5d0fbd9e6320017a264c4ef2bd52947079e3c665bd6a768ff85780da1012e3672
languageName: node
linkType: hard

Expand Down
Loading