Quick Start: Your First Table

Turn a published Google Sheet or a JSON endpoint into a live, searchable WordPress table in a couple of minutes — either by hand with the [tablecrafter] shortcode or visually with the built-in admin generator.

Short TagGoogle SheetsJSON APIVisual GeneratorZero Database

What you'll build

TableCrafter renders a table directly from an external data source — no rows are stored in your WordPress database. You point the plugin at a URL, it fetches and parses the data on your server, renders an accessible HTML table, and caches the result. By the end of this page you'll have a working table from two of the most common sources: a public Google Sheet and a JSON endpoint.

There is exactly one shortcode tag to learn: [tablecrafter]. The single attribute you can't skip is source; everything else is optional and has a sensible default.

ℹ️

TableCrafter fetches data server-side, so the table is rendered into the page HTML on first load (good for SEO) and works even when the browser can't reach the source directly. Remote responses are cached using a stale-while-revalidate strategy, so repeat views are fast.

Path A: The visual generator (recommended)

After activating the plugin, a top-level TableCrafter item appears in the WordPress admin sidebar (the table icon). This is the fastest way to produce a correct shortcode without memorizing attribute names.

  1. Go to WP Admin → TableCrafter.
  2. In the Settings card, paste your URL into Data Source URL. You can also click Upload File (CSV/JSON), Google Sheets, or Airtable for guided input.
  3. Optionally set Data Root (for nested JSON), Rows Per Page, and Include / Exclude columns.
  4. Toggle Enable Search, Enable Filters, and Enable Export to taste.
  5. Click Preview Table to render live data in the Live Preview pane and confirm it looks right.
  6. The Usage card shows the generated shortcode in real time. Click Copy Shortcode and paste it into any page or post.

The generator only writes out attributes that differ from defaults to keep your shortcode clean — for example, per_page is omitted when left at 10, and the search/filters/export toggles are always written explicitly ("true"/"false") so there's no ambiguity once it's on a page.

Path B: Write the shortcode by hand

If you prefer to type it, the minimal form is just a source URL:

[tablecrafter source="https://api.example.com/data.json"]

Add a few options to make it interactive:

# Search box + 10 rows per page
[tablecrafter source="https://api.example.com/data.json" search="true" per_page="10"]

Use it in a theme template

Because it's a standard shortcode, you can render it from PHP in any template file:

echo do_shortcode('[tablecrafter source="https://api.example.com/data.json" search="true"]');

End to end: a published Google Sheet

TableCrafter has first-class support for public Google Sheets. The sheet must be shared so that "Anyone with the link" can view it. You don't need to manually export anything — paste the normal browser URL and the plugin handles the conversion.

  1. In Google Sheets, choose Share and set link access to Anyone with the link → Viewer.
  2. Copy the address bar URL. It looks like the /edit#gid=0 link below.
  3. Drop it straight into the source attribute (or the admin Data Source URL field).
[tablecrafter source="https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit#gid=0"]

Behind the scenes, TableCrafter detects the docs.google.com/spreadsheets/d/<ID> pattern, extracts the sheet ID, and rewrites the request to the published-CSV endpoint:

# What the plugin actually fetches
https://docs.google.com/spreadsheets/d/<ID>/export?format=csv

If your URL includes a gid (a specific tab), that tab is preserved and appended to the CSV request, so you get the correct sheet rather than the first one. The first CSV row becomes your column headers; every following row becomes a table row.

⚠️

A private sheet returns Google's sign-in HTML instead of CSV, which won't parse into a table. If your Google Sheet table comes up empty, re-check that link sharing is set to Anyone with the link. The same CSV path also handles any URL ending in .csv.

End to end: a JSON endpoint

For a REST API or JSON file, point source at a URL that returns an array of objects. Each object is a row; the object keys become the column headers.

# A top-level JSON array — works with no extra attributes
[tablecrafter source="https://example.com/wp-content/uploads/products.json" search="true" export="true"]

Reaching a nested array with root

Many APIs wrap their records inside an object, e.g. { "data": { "results": [ ... ] } }. Use the root attribute with a dot-separated path to tell TableCrafter where the array lives:

[tablecrafter source="https://api.example.com/v1/report" root="data.results"]

The plugin walks each segment of the path (data then results) down to the array. If a segment doesn't exist, an admin-only error explains exactly which key was missing, so misconfiguration is easy to spot while logged in. End users never see the raw error — they get a friendly "Unable to load data" message instead.

ℹ️

If the source returns a simple list of scalar values (e.g. ["red","green","blue"]) instead of objects, TableCrafter auto-wraps each item into a single-column Value table so it still renders cleanly.

Shortcode attribute reference

These are the attributes accepted by [tablecrafter]. Booleans accept true/false (also 1/yes).

AttributeRequiredDefaultDescription
sourceRequired(empty)URL of the JSON API, JSON/CSV file, or public Google Sheet to display.
rootOptional(empty)Dot-path to the data array inside a JSON response, e.g. data.results.
searchOptionalfalseShow the live global search box.
filtersOptionaltrueShow auto-detected per-column filters.
exportOptionalfalseShow export tools (CSV, clipboard, and the genuine XLSX/PDF export added in 3.5.6).
per_pageOptional0Rows per page (0 = no client-side pagination).
includeOptional(empty)Comma-separated keys to show (curated columns).
excludeOptional(empty)Comma-separated keys to hide.
sortOptional(empty)Initial sort as column:direction, e.g. price:desc.
auto_refreshOptionalfalsePeriodically re-fetch the source for live data.
refresh_intervalOptional300000Refresh period in milliseconds (default 5 minutes).
refresh_indicatorOptionaltrueShow pause/resume refresh controls.
refresh_countdownOptionalfalseShow a countdown to the next refresh.
refresh_last_updatedOptionaltrueShow an "Updated X ago" timestamp.
idOptionalautoContainer element ID; auto-generated when omitted.

Curate and refine your columns

Heavy APIs often return more fields than you want on screen. Use include to whitelist columns or exclude to drop noisy ones:

# Show only these three columns
[tablecrafter source="https://api.example.com/coins.json" include="name,price,symbol"]

# Hide internal fields
[tablecrafter source="https://api.example.com/users.json" exclude="id,password_hash"]

Verify it works

Once your first table renders, layer on interactivity gradually: add search="true", then per_page, then export="true". Each is independent, so you can confirm one feature at a time.

Next steps

Now that you have a working table, explore connecting a live REST API in depth in data-sources.html, or turn your table into a self-updating dashboard with the options covered in auto-refresh.html.