diff --git a/packages/nextra-theme/src/components/DocSearch.tsx b/packages/nextra-theme/src/components/DocSearch.tsx
index 8237ea14b56a..f06cc52dafc8 100644
--- a/packages/nextra-theme/src/components/DocSearch.tsx
+++ b/packages/nextra-theme/src/components/DocSearch.tsx
@@ -65,7 +65,7 @@ export function DocSearch(props: DocSearchProps) {
         innerFocusRing
         sx={{
           borderRadius: [BorderRadius.FULL, null, null, BorderRadius.S],
-          '&:focus-visible': { outline: ['none', null, null, `${BorderWidth['4px']} solid ${theme.colors!.Purple16}`] },
+          '&:focus-visible': { outline: ['none', null, null, `${BorderWidth['4px']} solid ${theme.colors.Purple16}`] },
         }}
       >
         <Responsive.Multiple as="span" cases={['mobile', null, null, 'desktop']}>
@@ -158,17 +158,17 @@ export function DocSearch(props: DocSearchProps) {
             styles={{
               html: {
                 '--docsearch-spacing': '0 !important',
-                '--docsearch-container-background': `${theme.colors!.Midnight88} !important`,
+                '--docsearch-container-background': `${theme.colors.Midnight88} !important`,
                 '--docsearch-modal-width': 'min(calc(100vw - 32px), 840px) !important',
-                '--docsearch-modal-background': `${theme.colors!.Tooltip} !important`,
+                '--docsearch-modal-background': `${theme.colors.Tooltip} !important`,
                 '--docsearch-modal-shadow': 'none !important',
                 '--docsearch-searchbox-height': ['64px !important', null, '96px !important'],
                 '--docsearch-searchbox-focus-background': 'transparent !important',
                 '--docsearch-searchbox-shadow': 'none !important',
                 '--docsearch-hit-background': 'transparent !important',
-                '--docsearch-hit-color': `${theme.colors!.White88} !important`,
-                '--docsearch-hit-active-color': `${theme.colors!.White} !important`,
-                '--docsearch-highlight-color': `${theme.colors!.Purple} !important`,
+                '--docsearch-hit-color': `${theme.colors.White88} !important`,
+                '--docsearch-hit-active-color': `${theme.colors.White} !important`,
+                '--docsearch-highlight-color': `${theme.colors.Purple} !important`,
               },
               '.DocSearch-Container': {
                 animation: `${animationFadeIn} 150ms ease-in-out`,
diff --git a/website/pages/en/cookbook/_meta.js b/website/pages/en/cookbook/_meta.js
index f8b5035ddb55..d1e9e050cef0 100644
--- a/website/pages/en/cookbook/_meta.js
+++ b/website/pages/en/cookbook/_meta.js
@@ -1,4 +1,5 @@
 export default {
+  'subgraph-composition': '',
   'subgraph-debug-forking': '',
   near: '',
   cosmos: '',
diff --git a/website/pages/en/cookbook/subgraph-composition.mdx b/website/pages/en/cookbook/subgraph-composition.mdx
new file mode 100644
index 000000000000..14e8609fb7a7
--- /dev/null
+++ b/website/pages/en/cookbook/subgraph-composition.mdx
@@ -0,0 +1,127 @@
+---
+title: Subgraph Composition with Sushiswap v3 on Base
+---
+
+Leverage subgraph composition to create a base subgraph containing core data and build additional subgraphs on top.
+
+> - Subgraph composition is built into the CLI, and you can deploy with [Subgraph Studio](https://thegraph.com/studio/).
+> - You can use existing subgraphs, but they must be redeployed with a new spec version, which doesn't require you to write new code. However, you may want to restructure your subgraph to split out the logic as you move to a composable subgraph world.
+
+## Overview
+
+### Benefits of Composition
+
+Subgraph composition is a powerful feature for scaling, allowing you to:
+
+- Reuse existing data
+- Speed up your subgraph's syncing speed
+- Handle errors and optimize the resync
+- Enhance your subgraph development to effortlessly scale
+
+## Setup
+
+This guide uses the Sushiswap v3 subgraph on Base chain.
+
+### Tools Needed
+
+The setup involves two subgraphs:
+
+1. **Source Subgraph**: Tracks event data as entities.
+2. **Dependent Subgraph**: Uses the source subgraph as a data source.
+
+You can find these in the `source` and `dependent` directories.
+
+- The **source subgraph** is a basic event-tracking subgraph that records events emitted by relevant contracts.
+- The **dependent subgraph** references the source subgraph as a data source, using the entities from the source as triggers.
+
+While the source subgraph is a standard subgraph, the dependent subgraph utilizes the subgraph composition feature.
+
+### Source Subgraph
+
+The source subgraph tracks events from the Sushiswap v3 subgraph on the Base chain. This subgraph's configuration file is in the `source/subgraph.yaml`.
+
+### Dependent Subgraph
+
+The dependent subgraph is in the `dependent/subgraph.yaml` directory, which specifies the source subgraph as a data source. This subgraph uses entities from the source to trigger specific actions based on changes to those entities.
+
+## Get Started
+
+The following is a how-to-guide on using one subgraph as a data source for another.
+
+### Step 1. Set Up Your Source Subgraph
+
+To set the source subgraph as a data source in the dependent subgraph, include the following in `subgraph.yaml`:
+
+```yaml
+specVersion: 1.3.0
+schema:
+  file: ./schema.graphql
+dataSources:
+  - kind: subgraph
+    name: Factory
+    network: base
+    source:
+      address: 'QmdXu8byAFCGSDWsB5gMQjWr6GUvEVB7S1hemfxNuomerz'
+      startBlock: 82522
+```
+
+Here, `source.address` refers to the Deployment ID of the source subgraph, and `startBlock` specifies the block from which indexing should begin.
+
+### Step 2. Define Handlers in Dependent Subgraph
+
+Below is an example of defining handlers in the dependent subgraph:
+
+```typescript
+export function handleInitialize(trigger: EntityTrigger<Initialize>): void {
+  if (trigger.operation === EntityOp.Create) {
+    let entity = trigger.data
+    let poolAddressParam = Address.fromBytes(entity.poolAddress)
+
+    // Update pool sqrt price and tick
+    let pool = Pool.load(poolAddressParam.toHexString()) as Pool
+    pool.sqrtPrice = entity.sqrtPriceX96
+    pool.tick = BigInt.fromI32(entity.tick)
+    pool.save()
+
+    // Update token prices
+    let token0 = Token.load(pool.token0) as Token
+    let token1 = Token.load(pool.token1) as Token
+
+    // Update ETH price in USD
+    let bundle = Bundle.load('1') as Bundle
+    bundle.ethPriceUSD = getEthPriceInUSD()
+    bundle.save()
+
+    updatePoolDayData(entity)
+    updatePoolHourData(entity)
+
+    // Update derived ETH price for tokens
+    token0.derivedETH = findEthPerToken(token0)
+    token1.derivedETH = findEthPerToken(token1)
+    token0.save()
+    token1.save()
+  }
+}
+```
+
+In this example, the `handleInitialize` function is triggered when a new `Initialize` entity is created in the source subgraph, passed as `EntityTrigger<Initialize>`. The handler updates the pool and token entities based on data from the new `Initialize` entity.
+
+`EntityTrigger` has three fields:
+
+1. `operation`: Specifies the operation type, which can be `Create`, `Modify`, or `Remove`.
+2. `type`: Indicates the entity type.
+3. `data`: Contains the entity data.
+
+Developers can then determine specific actions for the entity data based on the operation type.
+
+## Key Takeaways
+
+- Use this powerful tool to scale your subgraph development and reuse existing data.
+- The setup includes creating a base source subgraph and referencing it in a dependent subgraph.
+- You define handlers in the dependent subgraph to perform actions based on changes in the source subgraph's entities.
+
+This approach unlocks modularity and scalability, simplifying both development and maintenance efficiency.
+
+## Additional Resources
+
+To use other advance features in your subgraph check out [subgraph advance features](/developing/creating/advanced/) and the [subgraph composition repo](https://github.com/incrypto32/subgraph-composition-sample-subgraph).