How to Persist Column Visibility Preferences Across Page Loads

Updated July 2026 • 6 min read • By Fahad Murtaza • By Fahad Murtaza

TableCrafter table builder, connect Gravity Forms, Google Sheets, Airtable, CSV, or JSON data sources
TableCrafter table builder, connect Gravity Forms, Google Sheets, Airtable, CSV, or JSON data sources

TableCrafter's column visibility picker lets your visitors choose which columns to show or hide, and those choices survive page reloads automatically. This guide walks through enabling the picker, understanding how persistence works under the hood, and combining it with role-based column controls for more advanced setups. WordPress powers 43% of all websites globally (W3Techs, July 2026), and TableCrafter bridges the gap between the data you collect and the tables your users need to see, no custom PHP, no dashboard access required for viewers. The free version on WordPress.org supports CSV, JSON, Google Sheets, and Excel. Pro adds Gravity Forms, Airtable, Notion, WooCommerce, REST APIs, inline cell editing, export to CSV/PDF, role-based column visibility, and auto-refresh. Every table embeds on any page with a [tablecrafter] shortcode or the native Gutenberg block. External database connections via REST APIs reduce WordPress database query load by up to 55% (Kinsta performance analysis, 2024).

What is the Column Visibility Picker?

The column visibility picker is a Free toolbar button that appears above your table labeled Columns. Clicking it opens a dropdown containing one checkbox per column. Visitors tick or untick columns to show or hide them instantly, no page reload required.

When a visitor changes which columns are visible, TableCrafter immediately writes those choices to the browser's localStorage under a key scoped to the specific table (format: gt_col_vis_<table_id>). The next time the same visitor loads the page, even after closing the browser, restoreColumnVisibility() runs during initialization and re-applies those saved choices before the table is displayed. There is no server round-trip and no cookies involved.

Scope: Preferences are stored per browser, per table. If a visitor switches devices or clears their browser storage, the table resets to showing all columns, the same default every new visitor sees.

How Do I Enable the Column Picker in the Admin?

The picker is opt-in per table. To turn it on, open TableCrafter → Tables, click Edit on the table you want to configure, and look for the Show Column Picker checkbox in the Display settings panel. Save the table.

Internally, the admin saves this as a boolean field called show_column_picker in the table configuration. The sanitizer in class-gt-admin.php normalizes any truthy POST value to true and any absent or falsy value to false, so the stored value is always a clean boolean.

Once enabled, the frontend module column-visibility-picker.js is automatically enqueued on pages that include the table. The init() method calls initColumnPicker() at startup, this method is a no-op when config.show_column_picker is falsy, so there is no overhead when the picker is disabled.

If this step produces unexpected output, check the source data directly in the connected system. TableCrafter passes data through without modification — if a cell displays an unexpected value, the source record contains that value. Use the TableCrafter debug log (Settings > Advanced > Debug Mode) to trace the exact query sent to the source and the raw response received, which narrows the diagnosis to either a source-side or rendering-side issue.

How Does localStorage Persistence Work?

The persistence layer is straightforward and recovers gracefully from every edge case. Here is the flow in order:

  1. Toggle event: When a visitor checks or unchecks a column, toggleColumnVisibility(fieldId, visible) sets display: none (or removes it) on the corresponding th header and every td[data-field-id] cell in the table body.
  2. Write to storage: The same method reads the existing JSON object from localStorage.getItem('gt_col_vis_<table_id>'), updates the fieldId key to the new boolean, and writes it back with localStorage.setItem(). Both the read and the write are wrapped in try/catch blocks, so quota errors or private-browsing restrictions never break the table.
  3. Restore on load: When the page loads, initColumnPicker() reads the same storage key before rendering the dropdown. Any field ID stored as false is immediately hidden, and its corresponding checkbox is rendered unchecked. Fields with no entry, or with value true, are rendered visible and checked.
  4. Separate key per table: Each table uses its own key (gt_col_vis_42, gt_col_vis_99, etc.), so multiple tables on the same page or site never interfere with each other.
Private browsing: Some browsers block localStorage writes in private/incognito mode. TableCrafter wraps every storage call in a try/catch so the picker still works for the current session, preferences just will not persist after the window closes.

How Does Role-Based Column Visibility (Pro) Work?

Pro adds a second, server-enforced layer called column-level role visibility. While the column picker is a visitor preference tool, role visibility is an access-control tool: it hides columns from users who lack the required WordPress role, regardless of what is stored in their browser.

The configuration is a per-column map of allowed roles stored in column_role_visibility inside the table settings. The rules are:

On the frontend, applyColumnRoleVisibility() runs during init() after the table is rendered. It reads config.column_role_visibility (the allowed-roles map) and config.user_roles (the current user's roles, injected by the server at page load), then hides any [data-field-id] cells for columns the user cannot access.

Defense in depth: Column role visibility operates on the DOM after render. For truly sensitive data, also restrict which fields the server includes in the AJAX response, DOM-level hiding alone is not a security boundary.

How Does Filter State Persistence (Separate Feature) Work?

Column visibility persistence is one of three independent localStorage features in TableCrafter. For completeness:

All three systems use the same defensive pattern: scoped keys derived from the table's numeric ID, try/catch around every read and write, and graceful fallback to defaults when storage is unavailable.

The shortcode accepts all column and filter settings defined in the table builder as defaults, but you can override individual parameters inline. For example, `[tablecrafter id="1" per_page="25"]` overrides the default rows-per-page setting for this specific embed without changing the saved table configuration. This lets you reuse one table definition across multiple pages with different display requirements.

Troubleshooting

If the Columns button does not appear, work through these checks in order:

Frequently Asked Questions

What is the Column Visibility Picker?

The column visibility picker is a Free toolbar button that appears above your table labeled Columns. Clicking it opens a dropdown containing one checkbox per column. Visitors tick or untick columns to show or hide them instantly, no page reload required.

What Is TableCrafter?

TableCrafter is a WordPress plugin that turns data from Gravity Forms, Google Sheets, Airtable, Notion, REST APIs, CSV files, and WooCommerce into interactive, sortable, filterable frontend tables. Embed any table on any WordPress page with the [tablecrafter] shortcode or the native Gutenberg block. No PHP or custom development required. The free version supports CSV, JSON, Google Sheets, and Excel. Pro adds Gravity Forms, Airtable, Notion, WooCommerce, REST APIs, inline cell editing, export to CSV and PDF, role-based column visibility, and auto-refresh.

Does this require PHP or developer skills?

No. TableCrafter is configured entirely through the WordPress admin interface. You choose your data source, map fields to columns, and set display preferences using point-and-click controls. Embedding uses the [tablecrafter] shortcode or the native Gutenberg block.

Is the free version sufficient or do I need Pro?

The free plugin on WordPress.org supports CSV, JSON, Google Sheets, and Excel sources with unlimited tables, rows, and columns. Pro adds Gravity Forms, Airtable, Notion, WooCommerce, REST API sources, inline cell editing, bulk row actions, export to CSV and PDF, role-based column visibility, and auto-refresh every N seconds.

Ready to try it?

TableCrafter is free on WordPress.org. Pro unlocks inline editing, role-based permissions, and advanced data sources.

Filters applied to the table URL as query parameters persist if the user copies and shares the URL. This makes filtered views bookmarkable and shareable, which is particularly useful for team dashboards where different users need to see different default views of the same underlying table.

This configuration interacts with any caching or CDN layer active on your WordPress installation. If you use WP Rocket, LiteSpeed Cache, or a CDN such as Cloudflare, flush the page cache after making this change to ensure the updated configuration is reflected in the cached HTML served to visitors. TableCrafter's server-side output is regenerated on the next uncached request.