> For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://buildwithfern.com/learn/llms.txt. # Scroll walkthrough > Learn how to use the ScrollWalkthrough component in Fern Docs to pair prose steps with a code panel that follows the reader's scroll position. The `` component pairs a column of prose steps with a code panel pinned beside them. Each step or substep names a file and a line range. When it scrolls into view, the panel shows that file with the other lines dimmed. Use it for quickstarts and integration guides where successive steps add to the same few files. ## Usage A walkthrough can contain a single file or several. Declare each file once as a fenced code block inside the component, then point steps and substeps at it with `file` and a line range in `focus` or `highlight`. A step or substep that omits `file` keeps the previously targeted file. Set the [`reference` layout](/learn/docs/configuration/page-level-settings#layout) on pages built around a walkthrough. It gives the prose and the code panel the full content width. #### Install the SDK Add the Plant Store SDK to your project. **`Terminal (line 1)`** ```bash Terminal (line 1) npm install @plantstore/sdk ``` #### Create the client Point the client at your garden with an API key. Import the client. **`garden.ts (line 1)`** ```ts garden.ts (line 1) import { PlantStore } from "@plantstore/sdk"; ``` Construct it with your API key. **`garden.ts (lines 3-5)`** ```ts garden.ts (lines 3-5) const client = new PlantStore({ apiKey: process.env.PLANT_API_KEY, }); ``` #### Add a plant Create your first plant record. The `wateringDays` interval drives care reminders. **`garden.ts (lines 7-11)`** ```ts garden.ts (lines 7-11) await client.plants.create({ name: "Monstera deliciosa", light: "bright-indirect", wateringDays: 7, }); ``` #### Complete files **`Terminal`** ```bash Terminal npm install @plantstore/sdk ``` **`garden.ts`** ```ts garden.ts import { PlantStore } from "@plantstore/sdk"; const client = new PlantStore({ apiKey: process.env.PLANT_API_KEY, }); await client.plants.create({ name: "Monstera deliciosa", light: "bright-indirect", wateringDays: 7, }); ``` **`Markdown`** ````jsx Markdown Add the Plant Store SDK to your project. Point the client at your garden with an API key. Import the client. Construct it with your API key. Create your first plant record. The `wateringDays` interval drives care reminders. ```bash Terminal npm install @plantstore/sdk ``` ```ts garden.ts import { PlantStore } from "@plantstore/sdk"; const client = new PlantStore({ apiKey: process.env.PLANT_API_KEY, }); await client.plants.create({ name: "Monstera deliciosa", light: "bright-indirect", wateringDays: 7, }); ``` ```` On narrow screens the panel pins to the top of the viewport, step headers stop sticking, and each substep's code renders inline beneath it. ## Variants ### Wide layout Set `layout="wide"` to narrow the prose column and give the code panel more room. Pair it with `panelHeight` to set the panel's height. #### Fetch a plant Read a single plant by ID. **`garden.ts (lines 1-3)`** ```ts garden.ts (lines 1-3) const plant = await client.plants.get("monstera-1", { includeCareHistory: true, }); ``` #### Log a watering Record care events to keep the plant's schedule accurate. **`garden.ts (lines 5-8)`** ```ts garden.ts (lines 5-8) await client.plants.logWatering("monstera-1", { wateredAt: new Date().toISOString(), amountMl: 250, }); ``` #### Complete files **`garden.ts`** ```ts garden.ts const plant = await client.plants.get("monstera-1", { includeCareHistory: true, }); await client.plants.logWatering("monstera-1", { wateredAt: new Date().toISOString(), amountMl: 250, }); ``` **`Markdown`** ````jsx Markdown Read a single plant by ID. Record care events to keep the plant's schedule accurate. ```ts garden.ts const plant = await client.plants.get("monstera-1", { includeCareHistory: true, }); await client.plants.logWatering("monstera-1", { wateredAt: new Date().toISOString(), amountMl: 250, }); ``` ```` ### Bulleted substeps Set `substepStyle="bullet"` to mark substeps with dots instead of numbers. Use it when the substeps under a step aren't ordered. #### Configure care defaults Each field controls one reminder. Set the watering interval in days. **`garden.ts (line 2)`** ```ts garden.ts (line 2) wateringDays: 7, ``` Set the fertilizing interval in weeks. **`garden.ts (line 3)`** ```ts garden.ts (line 3) fertilizingWeeks: 6, ``` Choose where reminders are delivered. **`garden.ts (line 4)`** ```ts garden.ts (line 4) remindVia: "email", ``` #### Complete files **`garden.ts`** ```ts garden.ts await client.gardens.updateDefaults({ wateringDays: 7, fertilizingWeeks: 6, remindVia: "email", }); ``` **`Markdown`** ````jsx Markdown Each field controls one reminder. Set the watering interval in days. Set the fertilizing interval in weeks. Choose where reminders are delivered. ```ts garden.ts await client.gardens.updateDefaults({ wateringDays: 7, fertilizingWeeks: 6, remindVia: "email", }); ``` ```` ### Highlighted lines `focus` dims every line outside its range. `highlight` marks its range with an accent background and leaves the rest of the file at full contrast. Use `highlight` for steps where the surrounding code still matters. #### Configure the client Set your API key and a request timeout. **`garden.ts (lines 1-4)`** ```ts garden.ts (lines 1-4) const client = new PlantStore({ apiKey: process.env.PLANT_API_KEY, timeoutMs: 10000, }); ``` #### Shorten the watering interval Summer growth needs more frequent watering, so drop the interval to five days. **`garden.ts (line 8)`** ```ts garden.ts (line 8) wateringDays: 5, ``` #### Complete files **`garden.ts`** ```ts garden.ts const client = new PlantStore({ apiKey: process.env.PLANT_API_KEY, timeoutMs: 10000, }); await client.plants.update("monstera-1", { light: "bright-indirect", wateringDays: 5, }); ``` **`Markdown`** ````jsx Markdown Set your API key and a request timeout. Summer growth needs more frequent watering, so drop the interval to five days. ```ts garden.ts const client = new PlantStore({ apiKey: process.env.PLANT_API_KEY, timeoutMs: 10000, }); await client.plants.update("monstera-1", { light: "bright-indirect", wateringDays: 5, }); ``` ```` ## Properties ### `` properties **`layout`** `'default' | 'wide'` — default: default Column split. `wide` narrows the prose column to give the code panel more room. --- **`panelHeight`** `string` Height of the code panel as a CSS length, such as `32rem`. Defaults to a viewport-based height. --- **`stickyHeaders`** `boolean` — default: true Whether each step's header stays pinned while its substeps scroll. --- **`dim`** `boolean` — default: true Whether inactive steps and substeps fade out. --- **`substepStyle`** `'bullet' | 'step'` — default: step Whether substeps are marked with numbers (`step`) or dots (`bullet`). --- **`className`** `string` Additional CSS classes to apply to the walkthrough --- ### `` properties Inside a walkthrough, [``](/learn/docs/writing-content/components/steps) accepts these properties: **`title`** `string` The step's heading --- **`description`** `string` A short summary rendered under the title --- **`file`** `string | number` The file this step targets, matching a code block's title or its 0-based index among the walkthrough's code blocks. When omitted, the step keeps the previously targeted file. --- **`focus`** `string | number | number[]` Lines to focus in the targeted file, dimming the rest. Accepts a range string such as `1-5,8`, a single line number, or an array of line numbers. --- **`highlight`** `string | number | number[]` Lines to highlight in the targeted file, using the same formats as `focus`. --- **`startLine`** `number` The 1-based line the panel scrolls to when the step becomes active. Defaults to the first focused or highlighted line. --- **`id`** `string` The unique ID for the step, used for linking. Generated automatically when unset. --- ### `` properties **`title`** `string` A short heading rendered above the substep's prose --- **`file`** `string | number` The file this substep targets, matching a code block's title or its 0-based index. When omitted, the substep inherits the step's file. --- **`focus`** `string | number | number[]` Lines to focus in the targeted file, dimming the rest. Accepts a range string such as `1-5,8`, a single line number, or an array of line numbers. --- **`highlight`** `string | number | number[]` Lines to highlight in the targeted file, using the same formats as `focus`. --- **`startLine`** `number` The 1-based line the panel scrolls to when the substep becomes active. Defaults to the first focused or highlighted line. --- **`id`** `string` The unique ID for the substep, used for linking. Generated from the parent step when unset. --- > Learn how to use the ScrollWalkthrough component in Fern Docs to pair prose steps with a code panel that follows the reader's scroll position.