Features are files stored in the features/ directory that must include an init function and optionally update and load methods as explained in the Features Lifecycle.
The ConfigFeature class is extended by each feature to implement remote config handling. It provides the following methods:
getFeatureSettingEnabled(settingKeyName)For simple boolean settings, returns true if the setting is 'enabled'
For default Enabled use: this.getFeatureSettingEnabled(settingKeyName, 'enabled')
getFeatureSetting()Returns a specific setting from the feature settings
recomputeSiteObject()Recomputes the site object for the feature, e.g. when the URL has changed
The ConfigFeature class is also exportable and can be used by other scripts to build C-S-S like features that can handle remote configuration - currently used in autofill.js to handle site specific autofill rules.
Create a new content scope features file in src/features/ and register it in features.js.
Add the feature name to the features.js array.
Add breakage debug flags at appropriate places by calling ContentFeature.addDebugFlag(). This will help identify anomalies in breakage reports.
There are three stages that the content scope code is hooked into the platform:
loadload() and completes policy setup in init() to avoid race conditionsinitupdateWhen editing core lifecycle code (src/content-scope-features.js, src/utils.js) or the feature registry (src/features.js), preserve these behaviors:
load(), when isGloballyDisabled(args) is true (allowlisted or broken sites), we still load platformSpecificFeatures.src/utils.js under platformSpecificFeatures.alwaysInitFeatures in src/content-scope-features.js (currently ['cookie']) bypasses isFeatureBroken for platform.name === 'extension'.cookie runs init() even on allowlisted/broken sites to complete policy setup.src/features/cookie.js installs the Document.cookie wrapper in load() before full config is available.load() seeds a best-effort policy from bundledConfig, then init() finalizes policy (including extension-provided args.cookie) and resolves loadedPolicyResolve.load(), extensions do not have site.enabledFeatures yet, so they fall back to platformSupport[import.meta.injectName].cookie) to install hooks on time.When developing features that modify web pages, add debug flags at appropriate times to help identify anomalies in breakage reports:
ContentFeature.addDebugFlag();
Key principles for feature development:
window or other globals should be avoided (pages could define same names)All features that modify web pages should use Privacy Remote Configuration where feasible. This allows:
The ConfigFeature class provides the infrastructure for this through getFeatureSettingEnabled() and getFeatureSetting() methods.