# Eject components tutorial

## Update tabs component behavior

Let's imagine you are writing a tutorial describing how to write code to work with your product.
You decided to use Redocly's [tabs](https://redocly.com/learn/markdoc/tags/tabs) Markdoc tag to show code examples in different languages.
As you are working, you decide it would be nice if a user could select their preferred programming language once.
That selection would update all other tabs on the page to the selected programming language.

But you notice, the Redocly [tabs](https://redocly.com/learn/markdoc/tags/tabs) Markdoc tag, does not have the ability to configure syncing between tabs.
So you decide to eject the component to update the behavior to allow configuring syncing between tabs.

## Eject the tabs component in the Redocly platform

For this tutorial we are going to eject the component using the [Redocly editor](/docs/platform/customization/eject-components/eject-components-in-platform).
To eject the component using the Redocly editor:

1. Select **Editor** on the left side navigation.
2. Click the **Theme components** in the **Files** section.
3. Search for **tabs**.
4. Find the **Tabs.tsx** component and click the eject icon.

After ejecting, the component is added to the `@theme` folder at the path `@theme/markdoc/components/Tabs/Tabs.tsx` where we can modify it.

## Implement `useTabs` hook

Create a new `useTabs.ts` file adjacent to the `Tabs.tsx` file and copy the code from the example.
You can also download all examples and drag and drop them to the `@theme/markdoc/components/Tabs` folder.

This custom hook reuses the original `useTabs` hook and adds syncing functionality between tabs with the same `syncId`.
It stores the `activeTab` state in `localStorage` after an update was triggered.
All other tabs are subscribed to the storage events to update their state.
Also, for initial mount, it gets the `activeTab` from `localStorage` to preserve the tabs state even after a page is reloaded.

**Prerequisites**

This tutorial does not provide step-by-step instructions for every customization.
Each case is unique and requires a different approach.
React, Markdoc and TypeScript knowledge is required to customize it.

## Replace the `useTabs` hook inside the Tabs component

Replace the original `useTabs` hook import with the custom hook.

Extend the `TabsProps` interface to include the `syncId` prop.

Add the `syncId` prop to the `Tabs` component.

And finally, pass the `syncId` prop to the `useTabs` hook.

## Extend the tabs Markdoc schema

We also need to update the tabs interface to be able to pass the `syncId` prop to the `tabs` Markdoc component.
That component passes the `syncId` to our modified `Tabs` React component.

### Eject the tags Markdoc schema

1. Select **Editor** on the left side navigation.
2. Click the **Theme components** in the **Files** section.
3. Search for **tabs**.
4. Find the **tabs.ts** tag and click the eject icon.

Add the `syncId` Markdoc attribute to the `tabs` tag.

To fix a warning, let's redefine our Markdoc schema.
Create a new `schema.ts` inside the `@theme/markdoc` folder and copy the code from the example.

## Create a tutorial page

To test our changes, let's create a `tutorial.md` page in the root of the project and copy the code from the example.

Your file structure should look like this:

```treeview
├── @theme/
│   └── markdoc/
│       ├── components/
│       │   └── Tabs/
│       │       ├── Tabs.tsx
│       │       └── useTabs.ts
│       ├── tags/
│       │   └── tabs.ts
│       └── schema.ts
└── tutorial.md
```

Since we added `syncId` attributes to the `tabs` tags, we can sync the tabs state between those tabs with the same `syncId`.

Test it out.
Do the tabs sync?

## 🎉 Congratulations

You have successfully ejected the `Tabs` component and added custom functionality to it.
Don't forget, with great power comes great responsibility, now you are responsible for maintaining the component 😉.
