How to Add ProfilePage Schema to Your WordPress Posts

James Parsons by James Parsons Updated Jul 16th, 2024

Here's a handy bit of code that lets you add the ProfilePage schema to your WordPress posts.

To install it, simply modify your info below and add it at the bottom of your functions.php file. You'll see the one I used on my site:

// Add ProfilePage schema to blog posts

function add_profilepage_schema() {
  // This is your author page URL
  if ($_SERVER['REQUEST_URI'] == '/author/james-parsons/') {
    echo '
    <script type="application/ld+json">
    {
      "@context": "https://schema.org",
      "@type": "ProfilePage",
      "mainEntity": {
        "@type": "Person",
        "name": "James Parsons",
        "image": "https://www.contentpowered.com/wp-content/uploads/2022/12/James-Parsons-Avatar-2022.jpg",
        "jobTitle": "Founder and CEO",
        "worksFor": {
          "@type": "Organization",
          "name": "Content Powered",
          "url": "https://www.contentpowered.com"
        },
        "description": "James Parsons is the founder and CEO of Content Powered. Having founded and grown several multi-million dollar eCommerce businesses solely through blogging, he created Content Powered to help other business owners grow their websites and sales by publishing useful, optimized, and well-researched content. He's also worked at several different agencies with roles ranging from Business Development Manager to CMO and was a major part of content marketing strategies for giant brands like eBay and Expedia.",
        "sameAs": [
          "https://www.linkedin.com/in/jamesparsonsdotcom/",
          "https://twitter.com/parsonsdotme",
          "https://jamesparsons.com/",
          "https://www.forbes.com/sites/forbeslacouncil/people/jamesparsons1/",
          "https://www.entrepreneur.com/author/james-parsons",
          "https://www.businessinsider.com/author/james-parsons",
          "https://www.inc.com/author/james-parsons",
          "https://www.huffpost.com/author/james-parsons"
        ],
        "knowsAbout": [
          "Internet Marketing",
          "Content Marketing",
          "Blogging",
          "Search Engine Optimization",
          "Conversion Rate Optimization",
          "Code"
        ],
        "address": {
          "@type": "PostalAddress",
          "streetAddress": "123 Your Street Address Lane",
          "addressLocality": "Beverly Hills",
          "addressRegion": "CA",
          "postalCode": "90210",
          "addressCountry": "USA"
        },
        "email": "[email protected]"
      }
    }
    </script>
    ';
  }
}
add_action('wp_head', 'add_profilepage_schema');

Now, a few notes.

First, with this line:

if ($_SERVER['REQUEST_URI'] == '/author/james-parsons/') {

This is your author profile URL. Replace it with yours.

Second, if you want this to show up on a different type of page or post type other than single blog posts, you can check out the WordPress guide on conditional tags. You may need to change is_single to your page or post type.

Lastly, if you have multiple authors, and you want to show a unique ProfilePage schema for each one, you'll need a more substantial piece of code, like this:

// Add ProfilePage schema to blog posts

function add_author_schema() {
  
  // Enter your company details
  
  $organization_name = 'Example Organization';
  $organization_url = 'https://www.example.com';
  $street_address = '123 Fake St, Ste 456';
  $address_locality = 'Faketown';
  $address_region = 'CA';
  $postal_code = '12345';
  $address_country = 'USA';  
  $authors = [
  
    // Author 1
    
    'author_username1' => [
      'name' => 'Author Name 1',
      'photo' => 'https://example.com/author1-photo.jpg',
      'jobTitle' => 'Job Title 1',
      'description' => 'Brief bio or description of Author Name 1',
      'sameAs' => [
        'https://linkedin.com/in/username1',
        'https://twitter.com/username1',
        'https://example.com'
      ],
      'knowsAbout' => [
        'Content Marketing',
        'Conversion Rate Optimization',
        'Search Engine Optimization',
        'Blogging',
        'Code',
        'Internet Marketing'
      ]
    ], 
    
    // Author 2
    
    'author_username2' => [
      'name' => 'Author Name 2',
      'photo' => 'https://example.com/author2-photo.jpg',
      'jobTitle' => 'Job Title 2',
      'description' => 'Brief bio or description of Author Name 2',
      'sameAs' => [
        'https://linkedin.com/in/username2',
        'https://twitter.com/username2',
        'https://example2.com'
      ],
      'knowsAbout' => [
        'Content Marketing',
        'Conversion Rate Optimization',
        'Search Engine Optimization',
        'Blogging',
        'Code',
        'Internet Marketing'
      ]
    ] // Add a comma after this bracket, if you're adding more authors. The last author should not have a comma after this bracket.
    
    // Copy more authors here as needed; be careful to use proper syntax and commas. 
  
  ];

  // Set the pattern in your blog URLs to look for. If your blog posts aren't posted to a subfolder (e.g. /blog/post-name), you can remove this part: && strpos($_SERVER['REQUEST_URI'], 'blog') !== false  
  if ( is_author() {
  
  // There should be no need to edit below this line
  
    global $post;
    $author_username = get_the_author_meta('user_nicename', $post->post_author);

    if ( array_key_exists($author_username, $authors) ) {
      $author = $authors[$author_username];
      $author_email = get_the_author_meta('user_email', $post->post_author);
      
      echo '
      <script type="application/ld+json">
      {
        "@context": "https://schema.org",
        "@type": "ProfilePage",
        "mainEntity": {
          "@type": "Person",
          "name": "' . esc_js( $author['name'] ) . '",
          "image": "' . esc_url( $author['photo'] ) . '",
          "jobTitle": "' . esc_js( $author['jobTitle'] ) . '",
          "worksFor": {
            "@type": "Organization",
            "name": "' . esc_js( $organization_name ) . '",
            "url": "' . esc_url( $organization_url ) . '"
          },
          "description": "' . esc_js( $author['description'] ) . '",
          "sameAs": ' . json_encode($author['sameAs']) . ',
          "knowsAbout": ' . json_encode($author['knowsAbout']) . ',
          "address": {
            "@type": "PostalAddress",
            "streetAddress": "' . esc_js( $street_address ) . '",
            "addressLocality": "' . esc_js( $address_locality ) . '",
            "addressRegion": "' . esc_js( $address_region ) . '",
            "postalCode": "' . esc_js( $postal_code ) . '",
            "addressCountry": "' . esc_js( $address_country ) . '"
          },
          "email": "' . esc_js( $author_email ) . '"
        }
      }
      </script>
      ';
    }
  }
}
add_action('wp_head', 'add_author_schema');

This checks the author of each post and populates their schema with their WordPress user information. You can add as many users as you need with this script.

Note: I'm the only author on my blog, so I use the first version. You may need to modify this to fit your specific needs, especially if you use custom post types or have an unusual setup.

Please let me know in the comments below if this code helped you or if you have any questions for me! Happy to help.

Related Code Snippets

Written by James Parsons

James Parsons is the founder and CEO of Content Powered, a premier content marketing agency that leverages nearly two decades of his experience in content marketing to drive business growth. Renowned for founding and scaling multi-million dollar eCommerce businesses through strategic content marketing, James has become a trusted voice in the industry, sharing his insights in Search Engine Watch, Search Engine Journal, Forbes, Entrepreneur, Inc, and other leading publications. His background encompasses key roles across various agencies, contributing to the content strategies of major brands like eBay and Expedia. James's expertise spans SEO, conversion rate optimization, and effective content strategies, making him a pivotal figure in the industry.