> ## Documentation Index
> Fetch the complete documentation index at: https://docs.siftstack.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Open Explore with a dynamic URL

> Construct a URL with query parameters to open Explore with Runs or Assets, Channels, Panel type, and an optional time range preloaded.

export const MintTable = ({columns = [], rows = [], columnWidths = []}) => {
  const pushTextWithLineBreaks = (parts, text, keyBase) => {
    const segments = String(text).split(/\\n|\n/);
    segments.forEach((segment, idx) => {
      if (segment) {
        parts.push(<span key={`${keyBase}-text-${idx}`}>{segment}</span>);
      }
      if (idx < segments.length - 1) {
        parts.push(<br key={`${keyBase}-br-${idx}`} />);
      }
    });
  };
  const parseMarkdown = text => {
    if (text === null || text === undefined) return "";
    const str = String(text);
    const parts = [];
    let lastIndex = 0;
    const pattern = /(`[^`]+`|\*\*[^*]+\*\*|\*[^*]+\*|\[([^\]]+)\]\(([^)]+)\))/g;
    let match;
    while (true) {
      match = pattern.exec(str);
      if (match === null) {
        break;
      }
      if (match.index > lastIndex) {
        pushTextWithLineBreaks(parts, str.substring(lastIndex, match.index), `before-${lastIndex}`);
      }
      const fullMatch = match[0];
      if (fullMatch.startsWith("`") && fullMatch.endsWith("`")) {
        parts.push(<code key={match.index}>{fullMatch.slice(1, -1)}</code>);
      } else if (fullMatch.startsWith("**") && fullMatch.endsWith("**")) {
        parts.push(<strong key={match.index}>{fullMatch.slice(2, -2)}</strong>);
      } else if (fullMatch.startsWith("*") && fullMatch.endsWith("*")) {
        parts.push(<em key={match.index}>{fullMatch.slice(1, -1)}</em>);
      } else if (fullMatch.startsWith("[")) {
        const linkText = match[2];
        const linkUrl = match[3];
        parts.push(<a key={match.index} href={linkUrl} className="text-black-600 dark:text-black-400">
            {linkText}
          </a>);
      }
      lastIndex = pattern.lastIndex;
    }
    if (lastIndex < str.length) {
      pushTextWithLineBreaks(parts, str.substring(lastIndex), `tail-${lastIndex}`);
    }
    if (parts.length > 0) {
      return parts;
    }
    const plainParts = [];
    pushTextWithLineBreaks(plainParts, str, "plain");
    return plainParts.length ? plainParts : str;
  };
  const safeColumns = Array.isArray(columns) ? columns : [];
  const safeRows = Array.isArray(rows) ? rows : [];
  const safeColumnWidths = Array.isArray(columnWidths) ? columnWidths : [];
  const hasColumnWidths = safeColumnWidths.some(w => w !== null && w !== undefined && w !== "");
  const toCssWidth = width => typeof width === "number" ? `${width}px` : String(width);
  const getColumnStyle = idx => {
    const rawWidth = safeColumnWidths[idx];
    if (rawWidth === null || rawWidth === undefined || rawWidth === "") {
      return undefined;
    }
    const width = toCssWidth(rawWidth);
    return {
      width,
      minWidth: width
    };
  };
  const containerStyle = hasColumnWidths ? undefined : {
    overflowX: "auto"
  };
  const tableStyle = hasColumnWidths ? {
    tableLayout: "fixed",
    width: "100%"
  } : {
    width: "max-content",
    minWidth: "100%"
  };
  if (!Array.isArray(columns) || !Array.isArray(rows) || !Array.isArray(columnWidths)) {
    console.warn("MintTable received invalid props:", {
      columns,
      rows,
      columnWidths
    });
  }
  if (!safeColumns.length && !safeRows.length) {
    return null;
  }
  return <div className="mint-table-container" style={containerStyle}>
      <table style={tableStyle}>
        {hasColumnWidths && <colgroup>
            {safeColumns.map((_, idx) => {
    const style = getColumnStyle(idx);
    return <col key={idx} style={style} />;
  })}
          </colgroup>}
        <thead>
          <tr>
            {safeColumns.map((col, idx) => <th key={idx} className="text-left" style={getColumnStyle(idx)}>
                <b>{parseMarkdown(col)}</b>
              </th>)}
          </tr>
        </thead>
        <tbody>
          {safeRows.map((row, rIdx) => {
    const safeRow = Array.isArray(row) ? row : [];
    return <tr key={rIdx}>
                {safeRow.map((cell, cIdx) => <td key={cIdx} style={getColumnStyle(cIdx)}>
                    {parseMarkdown(cell)}
                  </td>)}
              </tr>;
  })}
        </tbody>
      </table>
    </div>;
};

After completing this workflow, you can open Explore with telemetry data preloaded by sharing or navigating to a URL that specifies Runs or Assets, Channels, Panel type, and an optional time range, without any manual setup in the interface.

## Before you begin

* You must have access to an active Sift instance and know its domain name.
* You need the names or UUIDs of the Runs, Assets, or Channels you want to load.

## How it works

A dynamic URL is a link that opens Explore with specific data preloaded. You construct it by adding query parameters to the `/explore` route that define which Runs or Assets, Channels, Panel type, and time range to load.

When a user navigates to the URL, Explore opens with that data already selected, with no manual setup required. For the full URL structure and supported parameters, see [URL structure](/documentation/reference/explore-settings#url-structure) and [URL parameters](/documentation/reference/explore-settings#url-parameters).

For example, the following dynamic URL opens a Timeseries Panel with a single Channel on a single Run:

```
https://{domainName}/explore \
  ?method=single \
  &runs=runName \
  &channels=channelName \
  &panelType=timeseries
```

Dynamic URLs are constructed manually and let you define exactly what data loads on arrival. If you are already working in Explore, click <Icon icon="link" /> **Share**, then <Icon icon="copy" /> **Copy** to capture the current workspace state instead. See [Share](/documentation/reference/explore-settings#share).

## Create a dynamic URL

1. Start with your base URL:
   ```
   https://{domainName}/explore?method=single
   ```

2. Append parameters for the Runs or Assets you want to load. You can use names, UUIDs, or a mix:
   ```
   &runs=my-test-run
   &assetId=5161a578-c3f2-4ecb-8ea9-ae6fcbf3b3f0
   ```
   Run and Asset parameters can be combined in the same URL.

3. Append the Channels you want to plot. Add an axis or role prefix if needed:
   ```
   &channels=temperature,pressure
   &channels=L1:temperature,R1:pressure
   ```
   Channel names are matched case-insensitively. If a name cannot be resolved, a warning appears and remaining Channels still load.

4. Set the Panel type if you want something other than the default Timeseries Panel:
   ```
   &panelType=histogram
   ```

5. Optionally, define a time range:
   ```
   &startTime=2024-05-26T13:59:28.569Z \
   &endTime=2024-05-26T14:02:52.232Z
   ```

6. Join all parameters into a single continuous string with no spaces or backslashes, and share or navigate to the URL.

## Verify

Navigate to the constructed URL. Confirm that the expected Runs or Assets, Channels, and Panel type load automatically. If a name cannot be resolved, a warning appears in Explore and the remaining selections still load.

## Examples

### Data source selection

#### Run by name

Selects a Run by name and plots two Channels.

```
https://app.siftstack.com/explore \
  ?method=single \
  &runs=my-test-run \
  &channels=temperature,pressure
```

#### Asset by name with axis configuration

Selects an Asset by name and assigns Channels to different Y-axes.

```
https://app.siftstack.com/explore \
  ?method=single \
  &assets=my-asset \
  &channels=L1:temperature,R1:pressure
```

#### Mixed Run and Asset selection

Pre-selects multiple Runs and a single Asset. Run and Asset parameters can be combined, and multiple Runs can be provided as a comma-separated list.

```
https://app.siftstack.com/explore \
  ?method=single \
  &runIds=8bfc7a2a-de0c-402c-bec1-089f4a69f128,2fd5e1f9-d185-4f18-a31d-8f2aee20ef17 \
  &assetId=5161a578-c3f2-4ecb-8ea9-ae6fcbf3b3f0 \
  &panelType=timeseries
```

#### Mixed UUIDs and names

Specifies a Run by UUID and Channels using both a name and a UUID with an axis prefix.

```
https://app.siftstack.com/explore \
  ?method=single \
  &runs=8bfc7a2a-de0c-402c-bec1-089f4a69f128 \
  &channels=temperature,L2:8dad764f-fda2-4784-9132-ddc616df46c1
```

### Panel types

#### Timeseries with mixed axes

Plots Channels on different Y-axes using axis prefixes. For prefix syntax, see [Channel axis assignment](/documentation/reference/explore-settings#channel-axis-assignment).

```
https://app.siftstack.com/explore \
  ?method=single \
  &runId=8bfc7a2a-de0c-402c-bec1-089f4a69f128 \
  &assetIds=5161a578-c3f2-4ecb-8ea9-ae6fcbf3b3f0 \
  &panelType=timeseries \
  &channelIds=L1:df2cba99-abc2-4b36-bd16-e615b7682ace,L2:8dad764f-fda2-4784-9132-ddc616df46c1
```

#### Table view

Opens the Table Panel and evaluates selected Channels at the timestamp defined by `startTime`.

```
https://app.siftstack.com/explore \
  ?method=single \
  &runId=8bfc7a2a-de0c-402c-bec1-089f4a69f128 \
  &panelType=table \
  &channels=df2cba99-abc2-4b36-bd16-e615b7682ace,8dad764f-fda2-4784-9132-ddc616df46c1 \
  &startTime=2024-05-26T14:00:00.000Z
```

#### Histogram

Opens the Histogram Panel for a single Channel. If more than one Channel is provided, the first compatible Channel is used. For more on Channel compatibility by Panel type, see [Channel selection by Panel type](/documentation/reference/explore-settings#channel-selection-by-panel-type).

```
https://app.siftstack.com/explore \
  ?method=single \
  &runId=8bfc7a2a-de0c-402c-bec1-089f4a69f128 \
  &panelType=histogram \
  &channels=temperature
```

#### FFT

Opens the FFT Panel for a single numeric Channel.

```
https://app.siftstack.com/explore \
  ?method=single \
  &runId=8bfc7a2a-de0c-402c-bec1-089f4a69f128 \
  &panelType=fft \
  &channels=vibration
```

#### Metrics

Opens the Metrics Panel with several numeric Channels.

```
https://app.siftstack.com/explore \
  ?method=single \
  &runId=8bfc7a2a-de0c-402c-bec1-089f4a69f128 \
  &panelType=metrics \
  &channels=voltage,temperature,pressure
```

#### Scatter Plot with Channel roles

Assigns Channels to the X-axis, Y-axis, and color using role prefixes. The color Channel renders with a Viridis gradient by default. For the full list of supported role prefixes, see [Scatter Plot Channel roles](/documentation/reference/explore-settings#scatter-plot-channel-roles).

```
https://app.siftstack.com/explore \
  ?method=single \
  &runId=8bfc7a2a-de0c-402c-bec1-089f4a69f128 \
  &panelType=scatter-plot \
  &channels=x:velocity,y:pressure,color:temperature
```

#### Geo Map with Channel roles

Assigns latitude, longitude, and color Channels using role prefixes. Without role prefixes, the Geo Map Panel detects latitude and longitude Channels by name. For the full list of supported role prefixes, see [Geo Map Channel roles](/documentation/reference/explore-settings#geo-map-channel-roles).

```
https://app.siftstack.com/explore \
  ?method=single \
  &runId=8bfc7a2a-de0c-402c-bec1-089f4a69f128 \
  &panelType=geo-map \
  &channels=lat:location.latitude,lon:location.longitude,color:velocity
```

### Time range

#### Zoomed-in analysis

Focuses on a specific time window using `startTime` and `endTime`.

```
https://app.siftstack.com/explore \
  ?method=single \
  &runId=8bfc7a2a-de0c-402c-bec1-089f4a69f128 \
  &panelType=timeseries \
  &channels=L1:df2cba99-abc2-4b36-bd16-e615b7682ace \
  &startTime=2024-05-26T13:59:28.569Z \
  &endTime=2024-05-26T14:02:52.232Z
```

## Reference

* [Share](/documentation/reference/explore-settings#share)
* [Dynamic URLs](/documentation/reference/explore-settings#dynamic-urls)


## Related topics

- [Explore reference](/documentation/reference/explore-settings.md)
- [January 2026](/release-notes/2026/january-2026.md)
- [Explore (legacy) settings](/documentation/reference/explore-legacy-settings.md)
