Activation Window Feature
Overview
The Activation Window feature allows the browser to experiment with the first hours of a new profile’s lifetime by temporarily setting different defaults during a configurable time period (typically 48 hours). This enables:
Hiding or showing specific content sections (top sites, top stories) during the activation window
Displaying messaging when entering or exiting the activation window
Reverting to normal defaults after the activation window expires
Preserving user preference changes made during the activation window
The feature is controlled via Nimbus experiments using the newtabTrainhop feature with type: "activationWindowBehavior".
How It Works
High-level Architecture
Profile Creation Time Tracking (
AboutNewTab.sys.mjs)The browser computes the profile creation instant on startup using
ProfileAge.sys.mjsThe
createdInstantis cached on the ActivityStream instance for the session
Activation Window Evaluation (
PrefsFeed.sys.mjs)checkForActivationWindow()runs on:PrefsFeed initialization (startup)
Each NEW_TAB_STATE_REQUEST action (when opening a new tab)
It compares the current time against the profile age to determine if we’re within the activation window
Enters or exits activation window state as needed
Default Pref Manipulation
When entering the activation window: Sets default branch prefs for top sites/stories to experiment values
When exiting the activation window: Restores default branch prefs to original values
User pref values always override defaults, even after enabling and then re-disabling.
User Preference Tracking
Tracks user preference changes during the activation window
On exit, ensures that any user changes are persisted
State Broadcasting
Pref changes are broadcast to all content processes
StartupCacheInit queues changes for the cached about:home page if it exists
Messaging Integration
PrefsFeed sets message ID prefs on enter/exit:
activationWindow.enterMessageIDandactivationWindow.exitMessageIDASRouter messages can target these prefs using JEXL expressions
The
ActivationWindowMessagecomponent renders messages with bespoke UI (card layout with image, heading, message, and buttons)
Configuration
Nimbus Configuration Schema
The activation window is configured via Nimbus using the newtabTrainhop feature:
{
featureId: "newtabTrainhop",
value: {
type: "activationWindowBehavior",
payload: {
enabled: true,
maxProfileAgeInHours: 48,
disableTopSites: true,
disableTopStories: true,
variant: "a",
enterActivationWindowMessageID: "ACTIVATION_WINDOW_WELCOME_V1",
exitActivationWindowMessageID: "ACTIVATION_WINDOW_EXIT_V1"
}
}
}
Configuration Fields
enabled(boolean, default: false): Whether the activation window feature is activemaxProfileAgeInHours(number, default: 48): Duration of the activation window in hoursdisableTopSites(boolean, default: false): Hide top sites section during activation windowdisableTopStories(boolean, default: false): Hide top stories section during activation windowvariant(string, default: “”): Experiment variant identifierenterActivationWindowMessageID(string, default: “”): Message ID to show when entering the windowexitActivationWindowMessageID(string, default: “”): Message ID to show when exiting the window
Message Structure
Messages for the activation window use the ActivationWindowMessage component and follow this schema:
{
id: "MESSAGE_ID",
template: "newtab_message",
content: {
messageType: "ActivationWindowMessage",
// Heading: plain string or Fluent ID
heading: "Welcome to Your New Tab!",
// OR
heading: { string_id: "activation-window-welcome-heading-fluent-id" },
// Message: plain string or Fluent ID
message: "We've personalized your experience...",
// OR
message: { string_id: "activation-window-welcome-message-fluent-id" },
// Image (optional, defaults to kit-in-circle.svg if not provided)
imageSrc: "chrome://newtab/content/data/content/assets/kit.png",
primaryButton: {
// Plain text label (for tests)
label: "Learn More",
// OR Fluent ID label (for production)
label: { string_id: "activation-window-primary-button-fluent-id" },
action: {
type: "SHOW_PERSONALIZE"
}
},
secondaryButton: {
label: "Dismiss",
// OR
label: { string_id: "activation-window-secondary-button-fluent-id" },
action: { dismiss: true }
}
},
trigger: { id: "newtabMessageCheck" },
targeting: `'browser.newtabpage.activity-stream.activationWindow.enterMessageID' | preferenceValue == 'MESSAGE_ID'`,
groups: []
}
Message Content Fields
messageType(string, required): Must be"ActivationWindowMessage"heading(string or object, optional): Heading textPlain string:
"Welcome to Firefox"Fluent ID:
{ string_id: "activation-window-heading-fluent-id" }
message(string or object, optional): Message textPlain string:
"We've personalized your experience"Fluent ID:
{ string_id: "activation-window-message-fluent-id" }
imageSrc(string, optional): Chrome URL to image displayed in the message. If not provided, defaults to"chrome://newtab/content/data/content/assets/kit-in-circle.svg"primaryButton(object, optional): Configuration for primary button.secondaryButton(object, optional): Configuration for secondary button
Testing Locally
Using PanelTestProvider
Test messages are available in browser/components/asrouter/modules/PanelTestProvider.sys.mjs:
TEST_ACTIVATION_WINDOW_ENTER_MESSAGETEST_ACTIVATION_WINDOW_EXIT_MESSAGE
To test these messages:
Open
about:newtab#asrouterin FirefoxFind either the enter or exit message in the message list
Modify any of the parameters in the message as you’d like
Click “Show” or “Modify” to display the message
Open a new tab