# Recipe Structured Data for a Recipes Post Type

> Adds Recipe JSON-LD with times, servings, calories, ingredients, steps, cuisine and course to single recipes, for recipe rich results.

- Type: PHP
- Runs: Frontend only
- Category: [SEO](https://wpide.com/library/category/seo/)
- Tags: schema, recipes, json-ld
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/seo-recipe-schema/

## Code

```php
add_action( 'wp_head', function () {
    if ( ! is_singular( 'recipe' ) ) {
        return;
    }

    $post  = get_queried_object();
    $get   = function ( $key ) use ( $post ) {
        return trim( (string) get_post_meta( $post->ID, '_recipe_' . $key, true ) );
    };
    $lines = function ( $text ) {
        return array_values( array_filter( array_map( 'trim', explode( "\n", $text ) ) ) );
    };
    $terms = function ( $taxonomy ) use ( $post ) {
        $list = taxonomy_exists( $taxonomy ) ? get_the_terms( $post, $taxonomy ) : false;

        return ( $list && ! is_wp_error( $list ) ) ? implode( ', ', wp_list_pluck( $list, 'name' ) ) : '';
    };

    $prep = absint( $get( 'prep' ) );
    $cook = absint( $get( 'cook' ) );

    $data = array(
        '@context'           => 'https://schema.org',
        '@type'              => 'Recipe',
        'name'               => wp_strip_all_tags( get_the_title( $post ) ),
        'description'        => wp_strip_all_tags( get_the_excerpt( $post ) ),
        'image'              => get_the_post_thumbnail_url( $post, 'full' ),
        'author'             => array( '@type' => 'Person', 'name' => get_the_author_meta( 'display_name', $post->post_author ) ),
        'datePublished'      => get_the_date( DATE_W3C, $post ),
        'prepTime'           => $prep ? 'PT' . $prep . 'M' : '',
        'cookTime'           => $cook ? 'PT' . $cook . 'M' : '',
        'totalTime'          => ( $prep + $cook ) ? 'PT' . ( $prep + $cook ) . 'M' : '',
        'recipeYield'        => $get( 'servings' ) ? $get( 'servings' ) . ' servings' : '',
        'recipeCuisine'      => $terms( 'cuisine' ),
        'recipeCategory'     => $terms( 'recipe_course' ),
        'recipeIngredient'   => $lines( $get( 'ingredients' ) ),
        'recipeInstructions' => array_map( function ( $step ) {
            return array( '@type' => 'HowToStep', 'text' => $step );
        }, $lines( $get( 'steps' ) ) ),
    );

    if ( $get( 'calories' ) ) {
        $data['nutrition'] = array( '@type' => 'NutritionInformation', 'calories' => absint( $get( 'calories' ) ) . ' calories' );
    }

    echo '<script type="application/ld+json">' . wp_json_encode( array_filter( $data ), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_HEX_TAG ) . "</script>\n";
} );
```

## Notes

Reads the Recipe Details meta box fields and the Cuisine and Course taxonomies. Google requires a featured image.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Recipe Structured Data for a Recipes Post Type" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
