chrome.storage
- Description
Use the
chrome.storage
API to store, retrieve, and track changes to user data. - Permissions
storage
Overview
This API has been optimized to meet the specific storage needs of extensions. It provides the same storage capabilities as the localStorage API with the following key differences:
- User data can be automatically synced with Chrome sync (using
storage.sync
). - Your extension's content scripts can directly access user data without the need for a background page.
- A user's extension settings can be persisted even when using split incognito behavior.
- It's asynchronous with bulk read and write operations, and therefore faster than the blocking and serial
localStorage API
. - User data can be stored as objects (the
localStorage API
stores data in strings). - Enterprise policies configured by the administrator for the extension can be read (using
storage.managed
with a schema).
Manifest
You must declare the "storage" permission in the extension manifest to use the storage API. For example:
{
"name": "My extension",
...
"permissions": [
"storage"
],
...
}
Usage
To store user data for your extension, you can use either storage.sync
:
chrome.storage.sync.set({key: value}, function() {
console.log('Value is set to ' + value);
});
chrome.storage.sync.get(['key'], function(result) {
console.log('Value currently is ' + result.key);
});
or storage.local
:
chrome.storage.local.set({key: value}, function() {
console.log('Value is set to ' + value);
});
chrome.storage.local.get(['key'], function(result) {
console.log('Value currently is ' + result.key);
});
When using storage.sync
, the stored data will automatically be synced to any Chrome browser that the user is logged into, provided the user has sync enabled.
When Chrome is offline, Chrome stores the data locally. The next time the browser is online, Chrome syncs the data. Even if a user disables syncing, storage.sync
will still work. In this case, it will behave identically to storage.local
.
Confidential user information should not be stored! The storage area isn't encrypted.
The storage.managed
storage is read-only.
Storage and throttling limits
chrome.storage
is not a big truck. It's a series of tubes. And if you don't understand, those tubes can be filled, and if they are filled when you put your message in, it gets in line, and it's going to be delayed by anyone that puts into that tube enormous amounts of material.
For details on the current limits of the storage API, and what happens when those limits are exceeded, please see the quota information for sync and local.
Examples
The following sections demonstrate how to use chrome.storage
to address some common use cases.
Synchronous response to storage updates
If you're interested in tracking changes made to a data object, you can add a listener to its onChanged
event. Whenever anything changes in storage, that event fires. Here's sample code to listen for saved changes:
//// background.js ////
chrome.storage.onChanged.addListener(function (changes, namespace) {
for (let [key, { oldValue, newValue }] of Object.entries(changes)) {
console.log(
`Storage key "${key}" in namespace "${namespace}" changed.`,
`Old value was "${oldValue}", new value is "${newValue}".`
);
}
});
We can take this idea even further. In this example we have an options page that allows the user to toggle a "debug mode" in the extension (implementation not shown here). Changes to this setting are immediately saved to sync storage by the options page and the background script uses storage.onChanged
to apply the setting as soon as possible.
<!-- options.html -->
<script defer src="options.js"></script>
<form id="optionsForm">
<label for="debug">
<input type="checkbox" name="debug" id="debug">
Enable debug mode
</label>
</form>
//// options.js ////
// In-page cache of the user's options
const options = {};
// Initialize the form with the user's option settings
chrome.storage.sync.get('options', (data) => {
Object.assign(options, data.options);
optionsForm.debug.checked = Boolean(options.debug);
});
// Immediately persist options changes
optionsForm.debug.addEventListener('change', (event) => {
options.debug = event.target.checked;
chrome.storage.sync.set({options});
});
//// background.js ////
// Watch for changes to the user's options & apply them
chrome.storage.onChanged.addListener((changes, area) => {
if (area === 'sync' && changes.options?.newValue) {
const debugMode = Boolean(changes.options.newValue.debug);
console.log('enable debug mode?', debugMode);
setDebugMode(debugMode);
}
});
Asynchronous preload from storage
Since service workers are not always running, Manifest V3 extensions sometimes need to asynchronously load data from storage before they execute their event handlers. To do this, the below snippet uses an async action.onClicked
event handler that waits for the storageCache
global to be populated before executing its logic.
//// background.js ////
// Where we will expose all the data we retrieve from storage.sync.
const storageCache = {};
// Asynchronously retrieve data from storage.sync, then cache it.
const initStorageCache = getAllStorageSyncData().then(items => {
// Copy the data retrieved from storage into storageCache.
Object.assign(storageCache, items);
});
chrome.action.onClicked.addListener(async (tab) => {
try {
await initStorageCache;
} catch (e) {
// Handle error that occurred during storage initialization.
}
// Normal action handler logic.
});
// Reads all data out of storage.sync and exposes it via a promise.
//
// Note: Once the Storage API gains promise support, this function
// can be greatly simplified.
function getAllStorageSyncData() {
// Immediately return a promise and start asynchronous work
return new Promise((resolve, reject) => {
// Asynchronously fetch all data from storage.sync.
chrome.storage.sync.get(null, (items) => {
// Pass any observed errors down the promise chain.
if (chrome.runtime.lastError) {
return reject(chrome.runtime.lastError);
}
// Pass the data retrieved from storage down the promise chain.
resolve(items);
});
});
}
Summary
- Types
- Properties
- Events
Types
AccessLevel
The storage area's access level.
Type
"TRUSTED_CONTEXTS" "TRUSTED_AND_UNTRUSTED_CONTEXTS"
StorageArea
Properties
- onChanged
event
Chrome 73+Fired when one or more items change.
The
onChanged.addListener
function looks like:(callback: function) => {...}
- callback
function
The
callback
parameter looks like:(changes: object) => void
- changes
object
- clear
function
PromiseRemoves all items from storage.
The
clear
function looks like:(callback?: function) => {...}
- callback
function optional
The
callback
parameter looks like:() => void
- returns
Promise<void>
PendingThis only returns a
Promise
when thecallback
parameter is not specified, and with MV3+. The type inside thePromise
is the same as the 1st argument tocallback
.
- get
function
PromiseGets one or more items from storage.
The
get
function looks like:(keys?: string | string[] | object, callback?: function) => {...}
- keys
string | string[] | object optional
A single key to get, list of keys to get, or a dictionary specifying default values (see description of the object). An empty list or object will return an empty result object. Pass in
null
to get the entire contents of storage. - callback
function optional
The
callback
parameter looks like:(items: object) => void
- items
object
Object with items in their key-value mappings.
- returns
Promise<object>
PendingThis only returns a
Promise
when thecallback
parameter is not specified, and with MV3+. The type inside thePromise
is the same as the 1st argument tocallback
.
- getBytesInUse
function
PromiseGets the amount of space (in bytes) being used by one or more items.
The
getBytesInUse
function looks like:(keys?: string | string[], callback?: function) => {...}
- keys
string | string[] optional
A single key or list of keys to get the total usage for. An empty list will return 0. Pass in
null
to get the total usage of all of storage. - callback
function optional
The
callback
parameter looks like:(bytesInUse: number) => void
- bytesInUse
number
Amount of space being used in storage, in bytes.
- returns
Promise<number>
PendingThis only returns a
Promise
when thecallback
parameter is not specified, and with MV3+. The type inside thePromise
is the same as the 1st argument tocallback
.
- remove
function
PromiseRemoves one or more items from storage.
The
remove
function looks like:(keys: string | string[], callback?: function) => {...}
- keys
string | string[]
A single key or a list of keys for items to remove.
- callback
function optional
The
callback
parameter looks like:() => void
- returns
Promise<void>
PendingThis only returns a
Promise
when thecallback
parameter is not specified, and with MV3+. The type inside thePromise
is the same as the 1st argument tocallback
.
- set
function
PromiseSets multiple items.
The
set
function looks like:(items: object, callback?: function) => {...}
- items
object
An object which gives each key/value pair to update storage with. Any other key/value pairs in storage will not be affected.
Primitive values such as numbers will serialize as expected. Values with a
typeof
"object"
and"function"
will typically serialize to{}
, with the exception ofArray
(serializes as expected),Date
, andRegex
(serialize using theirString
representation). - callback
function optional
The
callback
parameter looks like:() => void
- returns
Promise<void>
PendingThis only returns a
Promise
when thecallback
parameter is not specified, and with MV3+. The type inside thePromise
is the same as the 1st argument tocallback
.
- setAccessLevel
function
Promise Chrome 102+Sets the desired access level for the storage area. The default will be only trusted contexts.
The
setAccessLevel
function looks like:(accessOptions: object, callback?: function) => {...}
- accessOptions
object
- accessLevel
The access level of the storage area.
- callback
function optional
The
callback
parameter looks like:() => void
- returns
Promise<void>
PendingThis only returns a
Promise
when thecallback
parameter is not specified, and with MV3+. The type inside thePromise
is the same as the 1st argument tocallback
.
StorageChange
Properties
- newValue
any optional
The new value of the item, if there is a new value.
- oldValue
any optional
The old value of the item, if there was an old value.
Properties
local
Items in the local
storage area are local to each machine.
Type
StorageArea & object
Properties
- QUOTA_BYTES
5242880
The maximum amount (in bytes) of data that can be stored in local storage, as measured by the JSON stringification of every value plus every key's length. This value will be ignored if the extension has the
unlimitedStorage
permission. Updates that would cause this limit to be exceeded fail immediately and setruntime.lastError
.
managed
Items in the managed
storage area are set by the domain administrator, and are read-only for the extension; trying to modify this namespace results in an error.
Type
session
Items in the session
storage area are stored in-memory and will not be persisted to disk.
Type
StorageArea & object
Properties
- QUOTA_BYTES
1048576
The maximum amount (in bytes) of data that can be stored in memory, as measured by estimating the dynamically allocated memory usage of every value and key. Updates that would cause this limit to be exceeded fail immediately and set
runtime.lastError
.
sync
Items in the sync
storage area are synced using Chrome Sync.
Type
StorageArea & object
Properties
- MAX_ITEMS
512
The maximum number of items that can be stored in sync storage. Updates that would cause this limit to be exceeded will fail immediately and set
runtime.lastError
. - MAX_SUSTAINED_WRITE_OPERATIONS_PER_MINUTE
1000000
DeprecatedThe storage.sync API no longer has a sustained write operation quota.
- MAX_WRITE_OPERATIONS_PER_HOUR
1800
The maximum number of
set
,remove
, orclear
operations that can be performed each hour. This is 1 every 2 seconds, a lower ceiling than the short term higher writes-per-minute limit.Updates that would cause this limit to be exceeded fail immediately and set
runtime.lastError
. - MAX_WRITE_OPERATIONS_PER_MINUTE
120
The maximum number of
set
,remove
, orclear
operations that can be performed each minute. This is 2 per second, providing higher throughput than writes-per-hour over a shorter period of time.Updates that would cause this limit to be exceeded fail immediately and set
runtime.lastError
. - QUOTA_BYTES
102400
The maximum total amount (in bytes) of data that can be stored in sync storage, as measured by the JSON stringification of every value plus every key's length. Updates that would cause this limit to be exceeded fail immediately and set
runtime.lastError
. - QUOTA_BYTES_PER_ITEM
8192
The maximum size (in bytes) of each individual item in sync storage, as measured by the JSON stringification of its value plus its key length. Updates containing items larger than this limit will fail immediately and set
runtime.lastError
.
Events
onChanged
chrome.storage.onChanged.addListener(
callback: function,
)
Fired when one or more items change.
Parameters
- callback
function
The
callback
parameter looks like:(changes: object, areaName: string) => void
- changes
object
- areaName
string