How to Build an Airtable-Powered Member Directory in WordPress

A member directory is one of the most practical things you can build with Airtable and TableCrafter. This end-to-end recipe covers everything: structuring the Airtable base, configuring the TableCrafter table, mapping the photo URL field to render images, enabling search by name, filtering by role, and placing the final shortcode. You will have a live, filterable directory on your WordPress site by the end. 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, and no per-row limits on the free tier. 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. Airtable has over 450,000 organization customers worldwide (Airtable, 2024).
What You Are Building?
The finished directory will:
This guide builds a single-page member directory that lives entirely on your WordPress site but is managed entirely from Airtable. You will not need to touch WordPress again after the initial setup: all member additions, updates, and deactivations happen in Airtable, and the directory on your WordPress site reflects those changes automatically within the configured cache window. The Airtable source is a Pro feature in TableCrafter, so you will need an active Pro license to connect the Airtable data source. Once connected, the number of members you can display is limited only by your Airtable plan's record count, there are no row limits imposed by TableCrafter itself.
This setting persists across table rebuilds. If you change the data source later, you may need to revisit this step to remap columns from the new source to the existing table configuration.
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.
- Display one row per member with their photo, name, role, bio snippet, and contact link
- Let visitors search by name in real time
- Let visitors filter by role using a dropdown
- Sort alphabetically by name by default
- Be fully managed in Airtable, adding or updating a member record in Airtable updates the directory automatically
Step 1: How Do I Set Up the Airtable Base?
Create a new Airtable base called Member Directory (or add a table to an existing base). In the table, create the following fields:
- Name, Single line text (this should be the primary field, the first column in Airtable)
- Role, Single select. Add your organization's roles as options, for example: Leadership, Member, Advisor, Alumni. Assign colors if desired.
- Bio, Long text. A 1-3 sentence description of the member.
- Photo URL, URL field. Store a direct link to the member's headshot. This can be a link to any publicly accessible image: your CDN, a cloud storage bucket, or a direct Airtable attachment URL.
- Email, Email field.
- LinkedIn, URL field. Optional but useful for professional directories.
- Active, Checkbox. Lets you hide former members without deleting their records.
Add a few test records before connecting to TableCrafter so you have data to preview.
Step 2: How Do I Create a Filtered Airtable View?
Rather than showing all members including inactive ones, create a filtered view in Airtable that TableCrafter will pull from.
- In your Members table, click + Add a view and choose Grid view. Name it
Active Members. - Add a filter: Active is checked.
- Sort by Name A → Z.
- Hide any internal-only fields you do not want TableCrafter to see (like admin notes).
You will point TableCrafter at this Active Members view. Any member you uncheck in Airtable disappears from the WordPress directory automatically, no changes needed on the WordPress side.
Using an Airtable view rather than the raw table gives you a second layer of control over what data reaches your public-facing directory. The view's sort order also becomes the default sort for TableCrafter when the page first loads, before the visitor applies any manual sorting. If you later need a different default order on the WordPress side, you can either update the Airtable view's sort or set a default sort override in the TableCrafter column configuration. Keeping the sort in Airtable is simpler for teams that already manage the base there, since any team member can update it without touching WordPress.
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.
Step 3: How Do I Create the Airtable Personal Access Token?
Go to airtable.com/create/tokens and create a token with:
- Scope:
data.records:read(read-only; we are not editing the directory from WordPress) - Access: your Member Directory base
Copy the token and store it securely.
Airtable personal access tokens are shown only once at creation time. If you close the page before copying the token, you must delete it and generate a new one. Store the token in a password manager or your team's secrets vault before pasting it into TableCrafter. Give the token a descriptive name like TableCrafter Member Directory so you can identify and rotate it later without disrupting other integrations that may use separate tokens.
Grant the token access to only the specific base it needs, not your entire workspace. If you have multiple Airtable bases, scoping the token to a single base limits the blast radius if the WordPress site were ever compromised. The data.records:read scope is sufficient for a read-only directory. Do not grant data.records:write unless you are also enabling inline editing that writes back to Airtable, which is a separate Pro configuration.
TableCrafter validates this configuration on save. If validation fails, the admin panel displays a specific error message identifying which field caused the problem. Correct the field value and save again without needing to restart the setup process.
When testing this feature, verify the result while logged in as a user with the target role, not as an admin. WordPress administrators see all rows and columns by default, which means admin accounts will not reflect role-restricted configurations during testing.
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.
Step 4: How Do I Create the TableCrafter Table?
- In WordPress, go to TableCrafter → Add New Table.
- Name it
Member Directory(this label appears in the admin table list and in the table title if you configure one). - Select Airtable as the data source type.
- Enter your personal access token, the base ID (the
appXXX...string from the Airtable URL), and the table name:Members(or whatever your Airtable table is named, this is case-sensitive). - In the View field, enter
Active Members. This filters your data at the Airtable API level, so only records visible in that view are pulled. If you leave the View field empty, all records in the table are included regardless of their status. - Click Test Connection. You should see your field names listed in the column selector below, one entry per Airtable field that the API returned for this table and view combination.
If the field list is empty or you see a connection error, the most common causes are an expired personal access token, a base ID that was copied incorrectly (it must start with app), or a view name with a typo. Regenerate your token in Airtable under Account → Developer hub and re-paste it if the connection was working before but stopped.
Step 5: How Do I Map the Columns?
With the connection confirmed, configure each column:
Photo URL Column
TableCrafter renders URL-type columns as raw links by default. Switching the column type to Image tells TableCrafter to fetch the URL stored in the Airtable field and render it as an inline thumbnail inside the table cell, rather than displaying the URL text. The image is loaded client-side from wherever the URL points, so no image is stored on your WordPress server. If your organization stores headshots in a CDN or cloud storage bucket with signed URLs, ensure those URLs are either permanent or long-lived enough to remain valid across the cache TTL.
- Find the Photo URL field in the column list.
- Set the Column Type to Image instead of URL.
- Set a thumbnail size,
60pxheight works well for a directory row. - Set the column label to Photo.
- Disable sorting and filtering for this column.
Name Column
The Name column is typically the primary field in Airtable, meaning it is the first column and serves as the record identifier. TableCrafter imports it like any other text field. Making it sortable allows visitors to re-sort the directory alphabetically, which is the most common interaction in a member directory. The global search bar in TableCrafter performs client-side filtering across all searchable columns, so Name is included automatically once search is enabled in the display settings. No additional search configuration is needed beyond enabling the search bar at the table level.
- Set column label to Name.
- Enable Sortable.
- This column participates in global search automatically.
Role Column
Airtable's Single select field type maps cleanly to a dropdown filter in TableCrafter. When you enable Filterable on this column, TableCrafter builds a dropdown control above the table populated with the distinct role values it finds in the data: your visitors can select Leadership, Member, Advisor, or any other option from the filter and the table narrows to matching rows instantly. The filter operates client-side for non-server-side-processing tables, meaning no additional Airtable API call is triggered on each filter change. Multiple roles can be selected in a single filter using the multi-select filter behavior, where the logic is OR within the filter: selecting Leadership and Member shows rows matching either role.
- Set column label to Role.
- TableCrafter auto-detects this as Single select and will render badges.
- Enable Filterable, this generates the dropdown filter by role.
Bio Column
Airtable Long text fields can hold several hundred characters or more. In a compact table row, a full bio disrupts the layout and makes the table harder to scan. TableCrafter's Max characters setting truncates the displayed text at the specified count and appends a "Read more" toggle that expands the full text inline without a page reload. Setting it to 150 characters preserves one to two sentences of context while keeping the row height consistent. Bios that are shorter than 150 characters are shown in full with no toggle. Disabling sort and filter for this column is correct since long text fields are not meaningful to sort or filter on in a member directory context.
- Set column label to About.
- Set a Max characters value of around 150 so long bios truncate gracefully in the table row. TableCrafter adds a “Read more” toggle.
- Disable sorting and filtering for this column.
Email Column
Airtable's Email field type is recognized by TableCrafter and rendered as a clickable mailto: link by default. Without a static link label, the full email address is displayed as the link text, which is fine for most directories. Setting a static label like Email or Contact hides the raw address from casual view while still making the link functional. This is worth considering if your members have asked to minimize how prominently their addresses appear in publicly accessible directories, since web scrapers can harvest email addresses from plain-text HTML. The mailto link still opens the visitor's default mail client with the correct address pre-filled regardless of how the label is configured.
- Set column label to Contact.
- TableCrafter renders email fields as
mailto:links automatically. - Optionally set a static link label like Email to hide the raw address from display.
LinkedIn Column
Airtable URL fields contain raw URLs. Without a static link label, TableCrafter would display the full LinkedIn URL, which is long and visually noisy in a table row. A static label like View Profile renders as a compact, clearly labeled link. Opening in a new tab is the correct behavior for external links in a directory: the visitor stays on your WordPress page while the LinkedIn profile opens in a separate browser tab. If a member has not provided a LinkedIn URL, the Airtable field will be empty and TableCrafter renders the cell as blank with no broken link. You can configure a custom fallback text for empty URL cells in the column settings if you prefer a placeholder like "Not listed".
- Set column label to LinkedIn.
- Column type: URL.
- Set a static link label of View Profile to render a clean link instead of the raw URL.
- Set Open in new tab to true.
Active Column
Toggle this column off entirely. Since you are already using the Active Members view in Airtable to filter, there is no need to display the Active checkbox in the table. Hiding it avoids confusion for visitors who might wonder why every visible row shows a checked box. If you were pulling from the unfiltered Airtable table instead of the view, you would want to keep this column visible and enable its filter so visitors could distinguish active from inactive members. With the view-based approach, the filtering happens at the Airtable API level before TableCrafter even receives the data, so inactive records never reach the WordPress table at all. This is the more performant pattern: filter early at the source rather than filtering a full dataset on the WordPress side.
Step 6: How Do I Configure Display Settings?
- Default sort: Name, ascending
- Rows per page: 25 (adjust based on your member count)
- Search bar: Enabled
- Filter bar: Enabled
- Edit mode: Disabled
- Export: Optional, enable if you want visitors to be able to download a CSV of members
- Cache TTL: 300 seconds (5 minutes), member directories change infrequently
Save the table. Note the table ID assigned (you will use it in the shortcode).
The 300-second cache TTL means TableCrafter fetches fresh data from Airtable at most once every five minutes per page load. Between fetches, the Airtable API is not called: the cached dataset is served from WordPress transients. This is a sensible default for a member directory, which changes infrequently. If you are building a directory for a live event where the speaker list updates in real time, reduce the TTL to 60 seconds or use the Clear Cache button in TableCrafter → Manage Tables to force an immediate re-fetch after any critical update. The Export option is worth enabling if your organization's administrators want to periodically download a CSV snapshot of the active members list for reporting or mailing list management.
If the result does not match expectations after saving, use the TableCrafter debug log (enable via TableCrafter Settings > Advanced > Debug Mode) to trace exactly which configuration value is being applied for the current request.
After completing this step, verify the result by viewing the page as a logged-out visitor in an incognito window. This confirms the table behaves correctly for public visitors rather than reflecting admin-level permissions that may hide configuration issues during initial setup. Check both the rendered output and the browser console for any JavaScript errors.
Step 7: How Do I Place the Shortcode?
Add the shortcode to a new WordPress page titled Member Directory:
[tablecrafter id="1" filter="true" search="true"]
Replace 1 with your actual table ID. Publish the page and visit it to confirm the directory renders correctly.
The filter="true" attribute activates the filter bar above the table so visitors can filter by Role. The search="true" attribute enables the search input. Both settings can also be toggled on permanently in the table's display configuration, at which point you do not need to include them in the shortcode explicitly. Including them in the shortcode is useful when you want the same table to appear in different modes on different pages: for example, search-enabled on a public directory page and search-disabled on an embedded widget with limited space. The shortcode attributes override the table-level defaults for that specific embed without changing the saved configuration.
Test this step while logged in as a user with the target role to confirm the expected behavior. Logged-in admin users always see all columns and all rows regardless of role restrictions, which can mask visibility issues during initial configuration.
The column mapping you define here is stored as a JSON configuration in the WordPress database. You can export this configuration using the TableCrafter export tool and import it to another table or another site. This is useful when replicating a table layout across multiple pages or when migrating a table to a staging environment for testing before going live.
Step 8: How Do I Test the Visitor Experience?
Before sharing the directory, verify these interactions work correctly:
TableCrafter re-fetches this data on each page load by default. If your data source updates infrequently and your site has significant traffic, enable the built-in caching option in the table's Performance tab. This stores the fetched data for a configurable number of minutes and serves it from WordPress transients, reducing API calls to the source and improving page load time for visitors.
- Type a name in the search bar and confirm rows filter in real time.
- Open the Role dropdown and select a role. Confirm only members with that role appear.
- Combine search and role filter. Confirm only matching rows appear.
- Click the Name column header to sort A–Z, then again for Z–A.
- Click an email link and confirm it opens your mail client.
- Click a LinkedIn link and confirm it opens in a new tab.
- Go to Airtable, add a new member record with Active checked, wait 5 minutes, and reload the directory. The new member should appear.
- Uncheck Active on a member in Airtable, wait 5 minutes, and reload. They should be gone from the directory.
How Does Handling Members Without Photos Work?
If a member's Photo URL field is empty in Airtable, the image cell renders blank by default. To show a fallback avatar instead:
- In the Photo column settings in TableCrafter, find Fallback Image URL.
- Enter the URL of a default avatar image hosted on your WordPress site or a CDN.
Members without a photo in Airtable will display the fallback avatar, keeping the directory visually consistent.
A common approach is to create a simple monogram-style placeholder image and host it in your WordPress media library. Use the media library URL as the fallback value in the column settings. This way the fallback image is served from the same domain as your WordPress site rather than an external CDN, which avoids potential cross-origin issues and keeps the asset under your control. If you later want to update the placeholder design, you can upload a new image and update the fallback URL in the column settings in one step, and every member without a photo switches to the new placeholder immediately on next page load.
The setting is stored in the WordPress options table under the table's configuration key. It does not modify the original data source and can be changed at any time without affecting the underlying records.
The configuration you set here applies to every visitor who loads a page containing this table, regardless of whether they are logged in. Role-specific overrides for columns and rows are a separate layer and do not replace these global display settings. Apply global settings first, then add role restrictions as needed for tables that serve multiple user types.
How Does Keeping the Directory Updated Work?
Because TableCrafter fetches from Airtable on demand (with a 5-minute cache), your directory update workflow is simply:
- Open the Airtable base.
- Add, edit, or deactivate a member record.
- Within 5 minutes, the WordPress directory reflects the change automatically.
No WordPress logins, no page edits, no plugin updates required. The Airtable base is the single source of truth.
This workflow is particularly valuable for organizations where the people maintaining the member list (HR teams, community managers, event organizers) are not WordPress administrators and should not have access to the CMS. They manage the Airtable base they already know, and the WordPress directory updates itself. You can also leverage Airtable's own automation features: for example, an Airtable automation can set a member's Active checkbox to unchecked when their membership expiration date passes, which would automatically remove them from the WordPress directory on the next cache refresh, with no manual action required from anyone.
This step completes the connection between your data source and the TableCrafter table engine. Once saved, the plugin caches the connection credentials in the WordPress options table and uses them on every subsequent page load. If you update the source configuration later, for example, rotating an API key or changing a sheet URL, return to this step, enter the new value, and save again. The table updates immediately on next load without any shortcode changes.
Frequently Asked Questions
How Do I Set Up the Airtable Base?
Create a new Airtable base called Member Directory (or add a table to an existing base). In the table, create the following fields:
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.
Changes take effect immediately after saving. No cache flush or page refresh is required for the new configuration to apply to all shortcode instances of this table.
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.