Errors when using react-tabs in an Astro page
I am unable to get this component running in the astro framework.
To reproduce you can create a new astro app with react support, e.g.
yarn create astro
cd to-your-project
yarn astro add react
# I had to add vite manually currently to get react support, maybe it works for you without
yarn add vite -D
# now add react-tabs
yarn add react-tabs
now just create a page like this and enable client scripting
---
import Layout from '../layouts/Layout.astro';
import { Tabs, TabList, Tab, TabPanel } from 'react-tabs';
import 'react-tabs/style/react-tabs.css';
---
<Layout title="React Tabs">
<Tabs client:load>
<TabList client:load>
<Tab client:load>Tab 1</Tab>
<Tab client:load>Tab 2</Tab>
</TabList>
<TabPanel client:load>
Content for Tab 1
</TabPanel>
<TabPanel client:load>
Content for Tab 2
</TabPanel>
</Tabs>
</Layout>
The tab buttons are loaded, but not the content. Also clicking on tabs has no effect. There are also various browser console errors and warnings.
- Error: Uncaught (in promise) SyntaxError: Expected property name or '}' in JSON at position 1 (line 1 column 2) at JSON.parse (
) at f.start - Warning: Each child in a list should have a unique "key" prop. Check the top-level render call using
Any idea, what I might have misconfigured? Or is a change to the library needed to make it work?
Thanks
Hi there @1R053. This issue can be closed. I figured this out how to get this working with your help (I needed a reminder to add client:load). Using react components in Astro is a little more complicated due to Astro's hydration (this does allow you to ship React lazily, only if needed).
I want to ship React on first load anyway for something else however, so also use client:load. This is a little labourious, but what I do is, create another pure .jsx file defining your site's specific tabs component, that itself uses react-tabs, pretty much exactly as they are in react-tabs examples. I don't set client:load in the .jsx. Instead I import the .jsx component (e.g. react-tabs) into a .astro file and set the hydration condition (in my case client:load) on the component's prop in that, e.g.:
TwoBasicTabs.jsx
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
import 'react-tabs/style/react-tabs.css';
export default () => (
<Tabs>
<TabList>
<Tab>Title 1</Tab>
<Tab>Title 2</Tab>
</TabList>
<TabPanel>
<h2>Any content 1</h2>
</TabPanel>
<TabPanel>
<h2>Any content 2</h2>
</TabPanel>
</Tabs>
);
index.astro
---
import Layout from '../layouts/Layout.astro';
import TwoBasicTabs from '../components/TwoBasicTabs.jsx';
---
<Layout title="react-tabs in Astro example">
<TwoBasicTabs client:load/>
</Layout>
In the .astro file, static Content collections, e.g. from .mdx files can be passed in as props, instead of defining content in .jsx files in an Astro project.
Make sure your astro.config.mjs sets up React too, e.g.:
// @ts-check
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';
export default defineConfig({
integrations: [react(),],
});
Commands to reproduce:
pnpm create astro@latest
# Agree to install. Don't need a Git repo.
pnpm astro add react
# Yes to both. Accept changes to tsconfig.json
pnpm add react-tabs
pnpm dev
This was on Windows, with these versions:
"dependencies": {
"@astrojs/react": "^4.2.0",
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"astro": "^5.3.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-tabs": "^6.1.0"
}