@foxglove/embed-react
This package provides the <FoxgloveViewer />
component, providing a React API for embedding Foxglove in your application.
Installation
- npm
- yarn
npm install --save @foxglove/embed-react
yarn add @foxglove/embed-react
Examples
Basic Usage
import { FoxgloveViewer } from "@foxglove/embed-react";
function BasicExample() {
const [isReady, setIsReady] = useState(false);
return (
<div style={{ height: "100vh" }}>
<FoxgloveViewer
orgSlug="my-org"
onReady={() => setIsReady(true)}
onError={(error) => console.error("Error:", error)}
/>
{isReady && <div>Foxglove is ready!</div>}
</div>
);
}
With Data Source
import { useState } from "react";
import { FoxgloveViewer } from "@foxglove/embed-react";
import { type DataSource } from "@foxglove/embed";
function DataSourceExample() {
const [dataSource, setDataSource] = useState<DataSource | undefined>(undefined);
const handleFileSelect = async () => {
window
.showOpenFilePicker({
multiple: false,
types: [
{
description: ".bag, .db3, .ulg, .ulog, .mcap",
accept: {
"application/octet-stream": [".bag", ".db3", ".ulg", ".ulog", ".mcap"],
},
},
],
})
.then(async (handles) => {
const file = await handles[0]!.getFile();
setDataSource({
type: "file",
file,
});
});
};
return (
<div>
<button onClick={handleFileSelect}>Select File</button>
<FoxgloveViewer orgSlug="my-org" data={dataSource} />
</div>
);
}
With Layout
import { useState } from "react";
import { FoxgloveViewer } from "@foxglove/embed-react";
import { type OpaqueLayoutData } from "@foxglove/embed";
function LayoutExample() {
const [layout, setLayout] = useState<OpaqueLayoutData>(undefined);
const handleLayoutSelect = async () => {
window
.showOpenFilePicker({
multiple: false,
types: [
{
description: ".json",
accept: {
"application/json": [".json"],
},
},
],
})
.then(async (handles) => {
const file = await handles[0]!.getFile();
const layoutData = JSON.parse(await file.text());
setLayout(layoutData);
});
};
return (
<div>
<button onClick={handleLayoutSelect}>Load Layout</button>
<FoxgloveViewer orgSlug="my-org" layoutData={layout} />
</div>
);
}
With Color Scheme
import { useState } from "react";
import { FoxgloveViewer } from "@foxglove/embed-react";
function ColorSchemeExample() {
const [colorScheme, setColorScheme] = useState<"auto" | "light" | "dark">("auto");
return (
<div>
<select
value={colorScheme}
onChange={(e) => setColorScheme(e.target.value as "auto" | "light" | "dark")}
>
<option value="auto">Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
<FoxgloveViewer orgSlug="my-org" colorScheme={colorScheme} />
</div>
);
}
Overriding the default src
import { FoxgloveViewer } from "@foxglove/embed-react";
function SrcOverrideExample() {
return (
<div style={{ height: "100vh" }}>
<FoxgloveViewer src="http://localhost:8080/" />
</div>
);
}
With Extensions
warning
This functionality is not supported by all Foxglove versions and plans, so it may result in an error
event.
import { FoxgloveViewer } from "@foxglove/embed-react";
function ExtensionsExample() {
const [extensions, setExtensions] = useState([]);
const handleExtensionSelect = async () => {
const extensionFile = await openExtensionFile();
setExtensions([extensionFile]);
};
return (
<div>
<button onClick={handleExtensionSelect}>Install Extension</button>
<FoxgloveViewer src="http://localhost:8080/" extensions={extensions} />
</div>
);
}
Component Props
src
(optional)
- Type:
string
- Description: The URL where the Foxglove app is hosted. Defaults to
https://embed.foxglove.dev/
.
orgSlug
(optional)
- Type:
string
- Description: The Foxglove organization the user should be signed into. Passing this parameter is recommended so the user can be prompted to switch to the correct org if necessary.
data
(optional)
- Type:
DataSource
- Description: The data source to visualize in the Foxglove app.
layoutData
(optional)
- Type:
OpaqueLayoutData
- Description: The layout configuration object for the Foxglove app. This includes panel configurations, global variables, and playback settings.
extensions
(optional)
warning
This functionality is not supported by all Foxglove versions and plans, so it may result in an error
event.
- Type:
Array<string | File>
- Description: The extensions to install in the Foxglove app. Can be URLs pointing to .foxe file or .foxe File objects.
colorScheme
(optional)
- Type:
"light" | "dark" | "auto"
- Default:
"auto"
- Description: The color scheme to use in the Foxglove app.
className
(optional)
- Type:
string
- Description: CSS class name to apply to the container element.
style
(optional)
- Type:
React.CSSProperties
- Description: The style to apply to the container.
onReady
(optional)
- Type:
() => void
- Description: Callback function that is called when the Foxglove app is ready.
onError
(optional)
- Type:
(errorMsg: string) => void
- Description: Callback function that is called when the Foxglove app encounters an error when trying to update the data source, layout, or extensions.
Performance Considerations
The component includes performance warnings for frequently changing props. Consider memoizing the following props to avoid unnecessary re-renders:
data
- Data source changeslayoutData
- Layout configuration changesextensions
- Extension list changes
Requirements
- React 18 or higher
- For live data sources, the target must be accessible from the browser
Error Handling
The component provides error handling through the onError
callback, which reports errors that occur when updating the data
, layoutData
, or extensions
props.