Person Schema Example

How to structure personal information using Person Schema

Using Person Schema allows you to structure information about individuals, authors, team members, etc., so that AI models and search engines can better understand them.

Configure it as a global schema in nuxt.config.ts to automatically inject it into all pages:

nuxt.config.ts
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['nuxt-aeo'],
  aeo: {
    schemas: [
      {
        type: 'Person',
        name: 'Yeonju Lee',
        alternateName: 'Dewdew',
        jobTitle: 'Software Engineer / CDO',
        url: '/profile', // Relative URL - will be normalized to absolute
        image: '/images/profile.jpg', // Relative URL - will be normalized to absolute
        knowsAbout: ['Nuxt3', 'TypeScript', 'Supabase'],
        sameAs: [
          'https://github.com/dewdew', // Absolute URL - used as-is
          '/social/twitter', // Relative URL - will be normalized to absolute
        ],
        renderHtml: true, // Generate semantic HTML
        visuallyHidden: true, // Visually hide
      },
    ],
    autoInject: true,
  },
})

Page-Specific Usage

To add Person Schema only on specific pages, use the useSchema() composable:

Note: useSchema() automatically normalizes URLs:

  • Absolute URLs (starting with http:// or https://) are used as-is
  • Relative URLs are combined with the base URL (from useRequestURL() or app.baseURL)
  • URL normalization applies recursively to nested objects and arrays (e.g., sameAs[], worksFor.url)
  • Processes url, image, logo, and item properties throughout the schema
pages/example.vue
<script setup lang="ts">
useSchema({
  context: 'https://schema.org',
  type: 'Person',
  name: 'John Doe',
  jobTitle: 'Software Engineer',
  url: '/profile', // Relative URL - will be normalized to absolute
  image: '/images/profile.jpg', // Relative URL - will be normalized to absolute
  knowsAbout: ['JavaScript', 'TypeScript', 'Vue.js'],
  sameAs: [
    'https://github.com/johndoe', // Absolute URL - used as-is
    '/social/twitter', // Relative URL - will be normalized to absolute
  ],
  renderHtml: true, // Generate semantic HTML
  visuallyHidden: true, // Visually hide
})
</script>

Complete Example

Global Configuration Example

nuxt.config.ts
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['nuxt-aeo'],
  aeo: {
    schemas: [
      {
        type: 'Person',
        name: 'Yeonju Lee',
        alternateName: 'Dewdew',
        jobTitle: 'Software Engineer / CDO',
        url: '/profile', // Relative URL - will be normalized to absolute
        image: '/images/profile.jpg', // Relative URL - will be normalized to absolute
        description: 'Full-stack developer specializing in Nuxt and Vue.js',
        knowsAbout: ['Nuxt3', 'TypeScript', 'Supabase', 'Vue.js'],
        sameAs: [
          'https://github.com/dewdew', // Absolute URL - used as-is
          '/social/twitter', // Relative URL - will be normalized to absolute
          'https://linkedin.com/in/dewdew', // Absolute URL - used as-is
        ],
        worksFor: {
          type: 'Organization',
          name: 'Example Company',
        },
        renderHtml: true,
        visuallyHidden: true,
      },
    ],
    autoInject: true,
  },
})

Page-Specific Usage Example

pages/example.vue
<script setup lang="ts">
// Person data with mixed absolute and relative URLs
const person = {
  name: 'John Doe',
  alternateName: 'johndoe',
  jobTitle: 'Software Engineer',
  url: '/profile', // Relative URL - will be normalized to absolute
  image: '/images/profile.jpg', // Relative URL - will be normalized to absolute
  description: 'Full-stack developer with expertise in web application development.',
  knowsAbout: ['JavaScript', 'TypeScript', 'Vue.js', 'Nuxt', 'Node.js'],
  sameAs: [
    'https://github.com/johndoe', // Absolute URL - used as-is
    '/social/twitter', // Relative URL - will be normalized to absolute
    'https://linkedin.com/in/johndoe', // Absolute URL - used as-is
  ],
  worksFor: {
    name: 'Example Company',
  },
}

// Add Person Schema
useSchema({
  context: 'https://schema.org',
  type: 'Person',
  name: person.name,
  alternateName: person.alternateName,
  jobTitle: person.jobTitle,
  url: person.url,
  image: person.image,
  description: person.description,
  knowsAbout: person.knowsAbout,
  sameAs: person.sameAs,
  worksFor: {
    type: 'Organization',
    name: person.worksFor.name,
  },
  renderHtml: true,
  visuallyHidden: true,
})
</script>

Generated JSON-LD

The above example automatically adds the following JSON-LD script to the page <head>:

example.json
{
  "@context": "https://schema.org",
  "@type": "Person",
  "name": "John Doe",
  "alternateName": "johndoe",
  "jobTitle": "Software Engineer",
  "url": "https://example.com",
  "image": "https://example.com/profile.jpg",
  "description": "Full-stack developer with expertise in web application development.",
  "knowsAbout": [
    "JavaScript",
    "TypeScript",
    "Vue.js",
    "Nuxt",
    "Node.js"
  ],
  "sameAs": [
    "https://github.com/johndoe",
    "https://twitter.com/johndoe",
    "https://linkedin.com/in/johndoe"
  ],
  "worksFor": {
    "@type": "Organization",
    "name": "Example Company"
  }
}

Automatic Semantic HTML Generation

When using the renderHtml: true option, the following semantic HTML is automatically generated and injected into the page:

example.html
<div class="nuxt-aeo-semantic-person nuxt-aeo-visually-hidden" aria-hidden="true">
  <div itemscope itemtype="https://schema.org/Person">
    <span itemprop="name">John Doe</span>
    <span itemprop="alternateName">johndoe</span>
    <span itemprop="jobTitle">Software Engineer</span>
    <a itemprop="url" href="https://example.com">https://example.com</a>
    <span itemprop="knowsAbout">JavaScript</span>
    <span itemprop="knowsAbout">TypeScript</span>
    <span itemprop="knowsAbout">Vue.js</span>
    <!-- More skills... -->
  </div>
</div>

Key Properties

Required Properties

  • name: Person's name
  • alternateName: Alias, username, etc.
  • jobTitle: Job title
  • url: Personal website URL
  • image: Profile image URL
  • description: Description of the person
  • knowsAbout: Array of expertise areas or technical skills
  • sameAs: Array of social media profile links
  • worksFor: Organization information

Additional Properties

Person Schema supports many more properties. For details, refer to the Schema.org Person documentation.

Verification

  1. Open Developer Tools (F12)
  2. Check the <script type="application/ld+json"> tag in the Elements tab
  3. Verify that semantic HTML with the nuxt-aeo-semantic-person class is injected inside the body tag

Or you can run the following command in the Developer Tools console:

example.html
// Check semantic HTML
document.querySelectorAll('.nuxt-aeo-semantic-person').forEach(el => {
  console.log('✅ Person semantic HTML:', el.innerHTML)
})

// Check JSON-LD schema
document.querySelectorAll('script[type="application/ld+json"]').forEach(script => {
  const schema = JSON.parse(script.innerHTML)
  if (schema['@type'] === 'Person') {
    console.log('✅ Person JSON-LD:', schema)
  }
})

Notes

  • Using global configuration automatically injects Person information into all pages
  • context and type are automatically converted to @context and @type internally
  • Using the renderHtml: true option provides both JSON-LD and semantic HTML together to further optimize LLM crawling
  • Person Schema can be displayed in Google's Knowledge Graph
  • The knowsAbout property is useful for representing a person's areas of expertise or technical skills

Frequently Asked Questions

This page includes FAQPage Schema to help AI models and search engines understand common questions about this topic.

pages/example.vue
<script setup lang="ts">
useSchemaFaq({
  mainEntity: [
    {
      name: 'When should I use Person Schema?',
      acceptedAnswer: {
        text: 'Person Schema is used to structure information about individuals, authors, team members, etc. It can be used on blog author information, team introduction pages, profile pages, contact pages, and more. It helps AI models and search engines better understand personal information.',
      },
    },
    {
      name: 'What is the difference between global and page-specific configuration?',
      acceptedAnswer: {
        text: 'Global configuration (nuxt.config.ts) automatically injects Person Schema into all pages. This is useful when displaying the same personal information across the entire site. Page-specific configuration (useSchema()) is used when you want to add Person Schema only on specific pages, allowing you to display different personal information on each page.',
      },
    },
    {
      name: 'What is the knowsAbout property?',
      acceptedAnswer: {
        text: 'The knowsAbout property represents the areas of expertise or technical skills that a person knows as an array. For example, you can list technical skills or areas of expertise like ["Nuxt3", "TypeScript", "Vue.js"]. This helps AI models understand the person\'s expertise.',
      },
    },
    {
      name: 'What are the renderHtml and visuallyHidden options?',
      acceptedAnswer: {
        text: 'Setting renderHtml to true automatically generates semantic HTML in Schema.org microdata format in addition to JSON-LD. Setting visuallyHidden to true hides the generated HTML visually so it is not visible to users, but AI models and search engines can read it. Using both options together further optimizes LLM crawling.',
      },
    },
  ],
})
</script>

Question List

  • When should I use Person Schema?: Used to structure information about individuals, authors, team members, etc., and can be used on blog author information, profile pages, and more
  • What is the difference between global and page-specific configuration?: Global configuration is automatically injected into all pages, while page-specific configuration is used only on specific pages
  • What is the knowsAbout property?: A property that represents a person's areas of expertise or technical skills as an array
  • What are the renderHtml and visuallyHidden options?: renderHtml generates semantic HTML, and visuallyHidden visually hides the generated HTML