Adding WordPress Custom Metadata using the REST API

Custom metadata in WordPress opens up a world of flexibility for developers, allowing you to store additional information on your posts and query posts based on that data. By adding custom metadata via the WordPress REST API and retrieving posts based on it, you can achieve custom filtering, personalized content displays, and much more. In this guide, I’ll walk you through how to set up custom metadata in WordPress, add it to your posts, and retrieve posts by specific metadata. Let’s dive into the steps needed to make it happen.

Thank me by sharing on Twitter 🙏

Custom Metadata in WordPress

WordPress is known for its flexibility and powerful content management capabilities. Custom metadata allows you to go beyond the standard fields and categories, enabling you to store unique information with each post. For example, you might want to store details like event dates, authors, or ratings, which can be invaluable when building more complex features like filtered lists or recommendation systems. In this tutorial, I’ll explain how to use the WordPress REST API to add and query custom metadata in a structured, repeatable way, making it easy to adapt for different use cases.

Step 1: Register Custom Metadata in WordPress

To begin, we need to register our custom metadata in WordPress so it can be managed via the REST API. This registration process not only makes our metadata accessible via the API but also ensures we can control its visibility and security.

In WordPress, custom metadata registration is done using PHP, specifically in the theme’s functions.php file or a custom plugin. Here’s an example where we’ll create a custom metadata field named custom_key:

PHP
function register_custom_meta_fields() {
    register_post_meta('post', 'custom_key', [
        'type' => 'string',
        'description' => 'A custom meta field',
        'single' => true,
        'show_in_rest' => true, // Enable REST API support
        'auth_callback' => function() {
            return current_user_can('edit_posts');
        },
    ]);
}
add_action('init', 'register_custom_meta_fields');

In this snippet:

  • We use register_post_meta() to define metadata for the post post type.
  • The show_in_rest property set to true makes the metadata accessible via the REST API.
  • auth_callback restricts access to users who can edit posts, ensuring data security.

With this step completed, we’re now set up to add metadata to our WordPress posts using the REST API.

Step 2: Adding Metadata to a Post Using the REST API

With our custom metadata registered, it’s time to add metadata to a specific post. This is where Axios and TypeScript come in handy, providing a structured, type-safe way to interact with the WordPress API.

To add metadata, we’ll make a PUT request to update an existing post’s metadata using the meta property. For the following example, let’s assume we have a valid WordPress REST API token for authentication. We’ll create a function addMetaToPost that accepts the post ID and metadata we want to add.

Here’s the TypeScript code for adding metadata:

TypeScript
import axios from 'axios';

interface PostMeta {
  custom_key: string;
}

interface UpdatePostResponse {
  id: number;
  meta: PostMeta;
}

const addMetaToPost = async (postId: number, meta: PostMeta) => {
  const url = `https://yourwordpresssite.com/wp-json/wp/v2/posts/${postId}`;

  try {
    const response = await axios.put<UpdatePostResponse>(
      url,
      { meta },
      {
        headers: {
          Authorization: `Bearer YOUR_ACCESS_TOKEN`,
          'Content-Type': 'application/json',
        },
      }
    );

    console.log('Metadata added successfully:', response.data);
    return response.data;
  } catch (error) {
    console.error('Error adding metadata:', error);
  }
};

// Usage
addMetaToPost(123, { custom_key: 'custom_value' });

In this code:

  • We define a PostMeta interface for type safety, which describes the shape of our metadata.
  • We use Axios to send a PUT request to the post’s URL, including the metadata in the request body.
  • The function logs a confirmation message if the metadata is added successfully.

Using this function, we can easily add metadata to any post by specifying the post ID and metadata values.

Step 3: Querying Posts by Metadata

Now that we can add custom metadata, let’s retrieve posts filtered by that metadata. By default, WordPress doesn’t allow querying posts by metadata directly via the REST API, so we’ll create a custom API endpoint to handle this.

To set up a custom endpoint for metadata-based queries, add the following code to your functions.php file:

TypeScript
function register_meta_query_endpoint() {
    register_rest_route('custom/v1', '/posts', [
        'methods' => 'GET',
        'callback' => 'get_posts_by_meta',
        'permission_callback' => '__return_true',
    ]);
}

add_action('rest_api_init', 'register_meta_query_endpoint');

function get_posts_by_meta($request) {
    $meta_key = $request->get_param('meta_key');
    $meta_value = $request->get_param('meta_value');

    $query = new WP_Query([
        'post_type' => 'post',
        'meta_query' => [
            [
                'key' => $meta_key,
                'value' => $meta_value,
                'compare' => '='
            ]
        ]
    ]);

    $posts = [];
    foreach ($query->posts as $post) {
        $posts[] = [
            'id' => $post->ID,
            'title' => get_the_title($post),
            'meta' => get_post_meta($post->ID)
        ];
    }

    return new WP_REST_Response($posts, 200);
}

With this code:

  • We register a new REST endpoint /custom/v1/posts to enable querying posts by metadata.
  • The endpoint accepts two parameters, meta_key and meta_value, which are used in a meta_query to filter posts.

Once this endpoint is set up, we can retrieve posts by metadata using Axios.

Step 4: Query Posts by Metadata Using Axios and TypeScript

With our custom endpoint in place, we’ll use Axios to query posts based on metadata. Let’s create a function queryPostsByMeta that accepts the metadata key and value we want to filter by.

TypeScript
import axios from 'axios';

interface Post {
  id: number;
  title: string;
  meta: PostMeta;
}

interface QueryPostsResponse {
  data: Post[];
}

const queryPostsByMeta = async (metaKey: string, metaValue: string) => {
  const url = `https://yourwordpresssite.com/wp-json/custom/v1/posts`;

  try {
    const response = await axios.get<QueryPostsResponse>(url, {
      params: {
        meta_key: metaKey,
        meta_value: metaValue,
      },
    });

    console.log('Queried posts:', response.data);
    return response.data;
  } catch (error) {
    console.error('Error querying posts:', error);
  }
};

// Usage
queryPostsByMeta('custom_key', 'custom_value');

In this function:

  • We define a Post interface to represent the structure of our returned posts.
  • The function sends a GET request to the custom endpoint with meta_key and meta_value as query parameters.
  • We log the results to confirm the queried posts match the metadata.

Using this function, we can easily retrieve posts based on custom metadata, opening up possibilities for filtered lists, personalized recommendations, and more.

Wrapping Up

Custom metadata in WordPress, when paired with the REST API, allows you to build sophisticated data-driven features for your site. By following the steps to register metadata, add it to posts, and query based on it, you can unlock advanced functionality, tailored content displays, and powerful filtering options. This guide covered everything from backend registration to API-based data handling with TypeScript and Axios, creating a flexible, robust way to manage custom metadata on any WordPress site.

Share this:

Leave a Reply