Nasaq
Components

SearchPerformanceTable

Queries or pages with clicks, impressions, CTR and average position, sortable, filterable and paginated, with change against the previous period.

PreviewOpen ↗

Code

import { SearchPerformanceTable } from "@fadymondy/nasaq/web";export function Queries() {  return (    <SearchPerformanceTable      rows={[{ id: "q1", label: "rtl react components", clicks: 420, impressions: 9800, position: 4.2, previousClicks: 380, previousPosition: 5.1 }]}    />  );}

SEO · beta

Live examples and controls: SearchPerformanceTable in the lab.

Install

npx shadcn@latest add https://docs.nasaqui.com/r/search-performance-table.json

SearchPerformanceTable is the Queries and Pages report of Search Console, built on DataTable. Each row has clicks, impressions, CTR and average position. CTR is computed from clicks and impressions when you do not give it. Position is lower-is-better, so a fall in position is shown as an improvement.

When to use

  • Search queries and landing pages with SEO metrics.
  • Any table of clicks, impressions, CTR and position.

When not to use

Import

import { SearchPerformanceTable } from "@fadymondy/nasaq/web";

Quick start

import { SearchPerformanceTable } from "@fadymondy/nasaq/web";

export function Queries() {
  return (
    <SearchPerformanceTable
      rows={[{ id: "q1", label: "rtl react components", clicks: 420, impressions: 9800, position: 4.2, previousClicks: 380, previousPosition: 5.1 }]}
    />
  );
}

Anatomy

SearchPerformanceTable  data-slot="search-performance-table"  (a Card)
  DataTableToolbar      filter box
  DataTable             label, clicks, impressions, CTR, position
  DataTablePagination

API

SearchPerformanceTable

PropTypeDefaultDescription
rowsreadonly SearchPerformanceRow[]required{ id, label, clicks, impressions, ctr?, position, previousClicks?, previousPosition? }.
kind"query" | "page"queryPicks the first column's heading, the filter placeholder and left-to-right labels for pages.
title / descriptionReactNodenoneCard header; defaults to "Search queries" or "Search pages".
pageSizenumber10Rows per page.
onRowClick(row) => voidnoneMakes rows clickable.
loadingbooleanfalseSkeleton.
error / onRetryReactNode / () => voidnoneError state with a retry button.
classNamestringnoneExtra classes on the root.
labelsPartial<SearchPerformanceTableLabels>noneReplace any built-in English or Arabic string.

Examples

Pages:

import { SearchPerformanceTable } from "@fadymondy/nasaq/web";

export const Pages = () => <SearchPerformanceTable kind="page" rows={[{ id: "p1", label: "https://nasaq.dev/docs", clicks: 900, impressions: 21000, position: 3.4 }]} />;

Row click opens details:

import { SearchPerformanceTable } from "@fadymondy/nasaq/web";

export const Clickable = () => <SearchPerformanceTable onRowClick={(row) => console.log(row.id)} rows={[{ id: "q", label: "hijri date picker", clicks: 90, impressions: 4200, position: 7.8 }]} />;

Accessibility

Built on DataTable: a real table, sortable headers with aria-sort, a labelled filter input and paginated rows. Clickable rows are focusable and respond to Enter. Position change is a signed number with an arrow, not colour alone.

RTL & i18n

  • Query text follows its own direction (dir="auto"); URLs stay left-to-right.
  • Numbers, CTR and position are bidi-isolated.
  • The filter box and pagination mirror.

Styling & tokens

  • Colours come from tokens (--primary, --nq-success, --nq-warning, --nq-danger, --nq-tag-*); never pass raw hex.
  • Improvements use --nq-success-text, declines --nq-danger-text.

Do / Don't

  • Do treat position as lower-is-better.
  • Don't show CTR you calculated from rounded numbers; pass the API's ctr.

Lab

https://docs.nasaqui.com/?path=/docs/components-seo-search-performance-table--docs

On this page