- What is Page State?
- Page State Structure
- Page State Bricks
- Isolating State with Namespaces
- Merge Strategy
- Example: Replace State
- Example: Shallow Merge
- Example: Deep Merge
- Common Patterns
- Run Extension Once
- Show Action Information in Sidebar Panel
- Append to an Array
What is Page State?
Page State is used to track data for reuse across extensions and runs of a single extension on the page. Common uses of Page State are:
- Track if an extension has already run on the page, e.g., to prevent it from running again
- Collect information from actions to show in a side panel
- Pass context to a page opened with the Open New Tab brick (also see )Multi-Page Automation
Page State Structure
The Page State is an object with properties and values. A value can be of any type, including nested objects and arrays.
Page State Bricks
There are two bricks for working with Page State:
Isolating State with Namespaces
The namespace
field controls which extensions/blueprints have access to the Page State. The primary purpose of namespace is to prevent other extensions from overwriting/corrupting the page state used by your extension/blueprint
- Shared: can be access by any extension/blueprint
- Blueprint (default): extensions in the same blueprint. If the extension is not part of a blueprint, behaves the same as shared. Use this to coordinate across extensions
- Extension: use this to track state for a single extension across runs
Merge Strategy
The mergeStrategy
of the “Set shared page state” brick controls how the values provided impact existing values:
- Shallow (default): properties provided overwrite existing properties. Other properties are preserved
- Replace: replace the page state with the new values
- Deep: merge properties, including nested objects. For arrays, items are merged pairwise. If two values are different types, the value is replaced
Example: Replace State
Before:
hasRun: false
message: "Some text"
Update
After
# The message field is removed, because the whole state is replaces
hasRun: true
Example: Shallow Merge
Before
hasRun: false
message: "Some text"
Update
After
hasRun: true
# The `message` key is not modified
message: "Some text"
Example: Deep Merge
Before: State
hasRun: false
exampleObject:
key1: "Text value"
Before: @data
exampleObject:
key2: "Key from @data object"
Update
After
hasRun: false
exampleObject:
key1: "Text value"
# key2 is deep merged into exampleObject
key2: "Key from @data object"
Common Patterns
Run Extension Once
To run an extension at most once, use the page state to track if the extension has been run.
In this example, we’ll set a hasExtensionRun
property on the extension’s state.
Use the Get shared page state brick to get the extension state. NOTE: use the “extension” namespace to isolate the state to this trigger
Cancel the trigger if the extension has already been run by passing @state.hasExtensionRun
for the condition:
When the extension has run, set the shared page state. Be sure to use the same namespace as used in the “Get shared page state” step:
Show Action Information in Sidebar Panel
This pattern uses two extensions:
- A context menu/button/trigger to fetch information
- A sidebar panel to show the information
In the first extension, fetch some data and store the data in the shared Page State with the the “Set shared page state brick”. Optional use the “Show Sidebar” brick to automatically open the PixieBrix sidebar:
blueprint
namespaceIn the Sidebar Panel extension, use the “Get shared page state” brick to get the state from the button:
In the panel, make sure to handle the case where the state has not been set yet. For example, use if/else tags in the template:
Append to an Array
In this pattern, the state will have an arrayExample
property that will track our array.
Get the shared page state
Use the jq brick to append to the array:
(.state.arrayExample // []) + [.data]
The // []
is used to handle the initial state of arrayExample
, where arrayExample is undefined because it has not been saved yet
Set the shared page state using the outputKey of the previous step: