Skip to main content

@foxglove/embed-react

This package provides the <FoxgloveViewer /> component, providing a React API for embedding Foxglove in your application.

Installation

npm install --save @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 changes
  • layoutData - Layout configuration changes
  • extensions - 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.