WordPress with Pods and WPGraphQL¶
Set up a WordPress backend for Silex with custom content types and GraphQL API.
Overview¶
WordPress is the primary CMS backend for Silex. Using two plugins, you can define custom content types, custom fields, and expose them via GraphQL:
- Pods — Create custom post types and custom fields (100% open source, GPL)
- WPGraphQL — GraphQL API for WordPress
Why Pods?¶
We recommend Pods because it is 100% open source (GPL), consistent with Silex's free/libre philosophy. Pods handles custom post types, custom fields, and custom taxonomies — all in one plugin, no extras needed.
The popular alternative, ACF (Advanced Custom Fields), has a free version with limited features and a commercial Pro version (~$99/year). Since Silex is a free and open-source project, we prefer to recommend tools that share the same values. See Using ACF instead if you already use it.
This approach lets designers bind Silex components to WordPress data without coding.
Prerequisites¶
- WordPress 5.9 or later
- PHP 7.4 or later
- WordPress admin access
- Silex instance with CMS enabled (default)
Installation¶
1. Install and activate plugins¶
In your WordPress admin:
- Go to Plugins → Add New
- Search for and install:
- Pods (free, open-source)
- WPGraphQL (free)
- Activate both
Or via WP-CLI:
2. Install WPGraphQL for Pods (if needed)¶
Pods fields may not appear in GraphQL by default. Add the integration plugin:
Or search for "WPGraphQL for Pods" in the plugin directory.
Defining content types¶
Create a custom post type¶
Using Pods:
- Go to Pods Admin → Edit Pods
- Click Add New
- Select Custom Post Type and configure:
- Pod Name:
blog_post(no spaces, lowercase) - Plural Label: Blog Posts
- Singular Label: Blog Post
- Description: Blog posts and articles
- Check: Show in REST API and Show in GraphQL
- Click Save Pod
Create custom fields with Pods¶
Custom fields are managed inside the Pod definition itself:
- Go to Pods Admin → Edit Pods
- Select the pod you want to add fields to (e.g., Blog Post)
- Click Add Field and configure each field:
- Featured Image (File / Image field)
- Author Name (Plain Text field)
- Excerpt (Paragraph Text field)
- Categories (Relationship field, linked to category)
- For each field, make sure Show in GraphQL is enabled in the field settings
- Click Save Pod
Map fields to GraphQL¶
With WPGraphQL + Pods (and the WPGraphQL for Pods plugin if needed), fields are exposed automatically. In the GraphQL explorer, they appear directly under the post type's fields:
{
blogPosts {
edges {
node {
id
title
content
featuredImage {
sourceUrl
}
authorName
excerpt
categories {
edges {
node {
name
}
}
}
}
}
}
}
Data contracts¶
A data contract defines the shape of data your Silex site expects. Document contracts before building the site.
Example: Blog post contract¶
// Data contract: Blog Post
{
type: "BlogPost",
fields: {
id: { type: "string", description: "Post ID" },
title: { type: "string", description: "Post title" },
slug: { type: "string", description: "Post slug (URL)" },
content: { type: "string", description: "Post content (HTML)" },
excerpt: { type: "string", description: "Short description" },
date: { type: "date", description: "Publication date" },
author: {
type: "object",
fields: {
name: { type: "string" },
avatar: { type: "string" },
}
},
featuredImage: {
type: "object",
fields: {
sourceUrl: { type: "string", description: "Image URL" },
altText: { type: "string", description: "Alt text" },
}
},
categories: {
type: "array",
items: {
type: "object",
fields: {
name: { type: "string" },
slug: { type: "string" },
}
}
}
}
}
Creating Pods fields to match contract¶
In Pods, create fields matching your contract by going to Pods Admin → Edit Pods → select your pod:
| Field Name | Field Type | Pods Settings |
|---|---|---|
| Excerpt | Paragraph Text | Max length 200 |
| Featured Image | File / Image | Single file |
| Author Name | Plain Text | Required |
| Categories | Relationship | Related to: Category |
Querying WordPress via GraphQL¶
Accessing the GraphQL API¶
After enabling WPGraphQL, access the GraphQL endpoint:
Or use GraphiQL explorer:
Example queries¶
Query all blog posts:
query GetBlogPosts {
blogPosts(first: 10) {
edges {
node {
id
title
slug
excerpt
date
featuredImage {
sourceUrl
altText
}
authorName
}
}
}
}
Query by category:
query GetPostsByCategory {
blogPosts(
first: 10
where: {
categoryName: "news"
}
) {
edges {
node {
id
title
slug
}
}
}
}
Query a single post:
query GetPost {
blogPostBy(slug: "my-first-post") {
id
title
content
authorName
featuredImage {
sourceUrl
}
}
}
Configuring Silex to use WordPress¶
In Silex editor¶
- Go to Settings → Page → CMS
- Click Add Data Source
- Configure:
- Name: WordPress
- Type: GraphQL
- URL: https://your-wordpress.com/graphql
- Backend: wordpress
- Click Save
In client config¶
Or set up in your client config file:
// client-config.js
export default async function (config) {
config.cmsConfig.dataSources = [
{
id: 'wordpress',
type: 'graphql',
url: 'https://my-wordpress.com/graphql',
backend: 'wordpress',
},
]
}
Server-side config (optional)¶
If you need to add custom logic on the server:
// .silex.js
module.exports = async function (config) {
// WordPress is built-in, no special config needed
// But you can customize if needed
}
Binding data in Silex¶
In the editor, create states that bind to WordPress data:
Loop over posts¶
- Add a Div component (will repeat for each post)
- Right panel → Data → Add State
- Configure:
- Name: posts
- Type: Query (GraphQL)
- Expression:
- Set Loop Over:
posts.edges
The component repeats for each post.
Bind text to post title¶
- Add a Text component inside the repeating div
- Right panel → Data → Add State
- innerHTML state:
- Expression:
node.title
The text displays the post title.
Display featured image¶
- Add an Image component
- Right panel → Data → Add State
- src state:
- Expression:
node.featuredImage.sourceUrl
Authentication and permissions¶
Public access (no auth)¶
By default, WPGraphQL allows public queries. This is fine for reading public posts.
Restrict to authenticated users¶
To limit queries to logged-in users, in WordPress:
- Install WPGraphQL Smart Cache (optional)
- Add to
wp-config.php:
Then in Silex, authenticate with WordPress credentials.
Personal data protection (GDPR)¶
If querying user data, ensure:
- Users opt-in to data exposure
- Queries don't include sensitive fields
- Privacy policy discloses data usage
Troubleshooting¶
GraphQL endpoint returns 404¶
Check:
- WPGraphQL plugin is activated
- URL is correct:
https://your-wordpress.com/graphql - Permalinks are set (WordPress Settings → Permalinks)
Try visiting /graphql directly in browser.
Pods fields not in GraphQL¶
Ensure:
- WPGraphQL for Pods plugin is installed and activated (if fields do not appear automatically)
- Show in GraphQL is enabled in the Pod settings for each pod and each field
- WPGraphQL is enabled for the post type
Go to Pods Admin → Edit Pods, select the pod, and verify each field has "Show in GraphQL" enabled.
Queries return null or empty¶
Check:
- Posts exist:
/wp-admin/edit.php?post_type=blog_post - Pods fields are filled in
- GraphQL query syntax is correct (use GraphiQL to test)
Authentication errors in Silex¶
If queries fail with auth errors:
- Check if WPGraphQL is public: try querying without auth
- If auth is required, you may need to pass credentials to Silex (contact support)
Performance issues¶
WordPress can be slow with large datasets. Optimize:
-
Paginate queries:
-
Limit fields: Only query fields you need
- Cache results: Use WPGraphQL Smart Cache plugin
- Upgrade hosting: More CPU/RAM helps
Best practices¶
Naming conventions¶
- Post type slug: lowercase with underscores (
blog_post,team_member) - Field names: lowercase with underscores (
featured_image,author_name) - Custom taxonomy: lowercase plural (
blog_categories,tags)
Field organization¶
Group related fields in your Pod definition:
- Content: title, content, excerpt
- Media: featured image, gallery
- Metadata: author, date, categories
Data validation¶
Use Pods field settings:
- Required fields: Prevent incomplete posts
- Field limits: Text area max length
- Conditional logic: Show fields based on other fields
Documentation¶
Document your data contract:
## WordPress Data Structure
### BlogPost post type
- `title` (string): Post title
- `content` (HTML): Main content
- `featuredImage.sourceUrl` (URL): Hero image
- `authorName` (string): Author name
- `categories[].name` (array): Post categories
Using ACF instead¶
If you prefer ACF (Advanced Custom Fields), the setup is similar. Install ACF + WPGraphQL for ACF instead of Pods. ACF Pro is a commercial plugin (~$99/year) that also handles custom fields and post types. The GraphQL query structure differs slightly: ACF fields appear under an acfFields wrapper (e.g., acfFields.featuredImage.sourceUrl instead of featuredImage.sourceUrl).
See also¶
- Client configuration and plugins — Client config CMS settings
- WordPress setup — Designer WordPress guide
- Binding data — Binding data in editor
- WPGraphQL docs — Complete API reference
- Pods docs — Pods framework documentation