Back to Seo

seo-meta

SEOmeta tagsOpen GraphTwitter CardJSON-LDstructured dataweb developmentmarketing
860📄 MIT🕒 2026-06-11Source ↗

Install this skill

npx skills add jezweb/claude-skills

Works across Claude Code, Cursor, Codex, Copilot & Antigravity

The seo-meta skill provides a standardized framework for implementing search engine optimization tags directly into web headers. It automates the generation of canonical links, Open Graph metadata for social sharing, and Twitter card protocols to ensure consistent display across external platforms. Beyond basic metadata, it includes a structured JSON-LD schema generator for local business entities, helping crawlers interpret site content such as address, telephone number, and business identity. By following specific character limits and syntactic formulas for titles and descriptions, this skill maintains high visibility in search engine result pages. It serves as a bridge between raw content and algorithmic requirements, ensuring that every page, from local service hubs to landing pages, adheres to industry-standard SEO patterns without manual configuration errors or keyword stuffing.

When to Use This Skill

  • Configuring site-wide SEO headers for a new local business landing page.
  • Updating legacy service pages to include modern social sharing images and descriptions.
  • Standardizing title and meta description formats across a multi-page local service site.
  • Injecting business location schema to improve local search map rankings.

How to Invoke This Skill

Example prompts that trigger this skill in Claude Code, Cursor, or Antigravity:

  • Add SEO metadata to this page
  • Generate meta tags for a service page
  • Create local business JSON-LD for my website
  • Fix my page title and meta description
  • Configure Open Graph and Twitter cards for this URL

Pro Tips

  • 💡Always include a unique `og:image` and `twitter:image` to ensure visually engaging social media shares, improving click-through rates.
  • 💡Test your Open Graph and Twitter Card tags using their respective validators (e.g., Facebook Sharing Debugger, Twitter Card Validator) to confirm correct display before publishing.
  • 💡Tailor `meta name="description"` to be distinct and action-oriented for search engines, and `og:description` for social media, often a slightly more concise version.

What this skill does

  • Generates validated Open Graph and Twitter card meta tags for social media previews.
  • Formats JSON-LD structured data for LocalBusiness Schema identification.
  • Enforces character-count constraints for titles and meta descriptions to prevent truncation.
  • Provides pre-built templates for home, service, location, and contact page metadata.
  • Handles canonical URL declaration to prevent duplicate content issues.

When not to use it

  • When managing highly dynamic, real-time content that requires server-side side-effect injection.
  • For complex e-commerce product catalogs that require product-specific schema beyond LocalBusiness.

Example workflow

  1. Define the target page type (Home, Service, or Location).
  2. Input the primary service and geographical location.
  3. Generate the title tag and description using the recommended character-conscious formulas.
  4. Construct the JSON-LD business object with specific address and contact data.
  5. Insert the generated meta blocks into the document head.
  6. Validate the output using a metadata preview tool or validator.

Prerequisites

  • Known business location details (address, phone number)
  • Primary service and location keywords
  • Access to the HTML document head section

Pitfalls & limitations

  • !Over-optimizing titles with keyword stuffing which can trigger search penalties.
  • !Using low-resolution images for og:image tags leading to pixelated social previews.
  • !Ignoring mobile-specific character limits resulting in truncated text on smaller screens.

FAQ

How many characters should my meta description be?
Aim for 120-160 characters to ensure the content remains visible on both desktop and mobile search results.
Why do I need a canonical link?
A canonical link tells search engines which version of a page is the 'master' copy, preventing issues where multiple URLs show the same content.
What image size works best for Open Graph?
Use a 1200x630px image with a 1.91:1 ratio to ensure proper rendering on social platforms like Facebook and LinkedIn.

How it compares

This skill enforces structured, proven patterns rather than relying on LLM-generated titles which often ignore character limits or local search nuances.

Source & trust

860 stars📄 MIT🕒 Updated 2026-06-11
📄 Full skill instructions — original source: jezweb/claude-skills
# SEO Meta Tags

**Status**: Production Ready ✅
**Last Updated**: 2026-01-14
**Source**: Schema.org, Open Graph Protocol, Twitter Developer Docs

---

## Quick Start

Every page needs:

<head>
{/* Basic SEO */}
<title>Service in Location | Brand Name</title>
<meta name="description" content="Value prop. Differentiator. Call to action." />
<link rel="canonical" href="https://example.com/page" />

{/* Open Graph */}
<meta property="og:title" content="Service in Location" />
<meta property="og:description" content="Value prop. Differentiator. CTA." />
<meta property="og:image" content="https://example.com/og-image.jpg" />
<meta property="og:url" content="https://example.com/page" />
<meta property="og:type" content="website" />

{/* Twitter Card */}
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Service in Location" />
<meta name="twitter:description" content="Value prop. Differentiator. CTA." />
<meta name="twitter:image" content="https://example.com/og-image.jpg" />

{/* JSON-LD Structured Data */}
<script type="application/ld+json">
{JSON.stringify({
"@context": "https://schema.org",
"@type": "LocalBusiness",
"name": "Business Name",
"description": "What we do",
"@id": "https://example.com",
"url": "https://example.com",
"telephone": "+61-XXX-XXX-XXX",
"address": {
"@type": "PostalAddress",
"streetAddress": "123 Main St",
"addressLocality": "Sydney",
"addressRegion": "NSW",
"postalCode": "2000",
"addressCountry": "AU"
}
})}
</script>
</head>


---

## Title Tag Patterns

**Character Limits**:
- Google: 50-60 characters (desktop), 78 (mobile)
- Social: 60-70 characters

**Page Type Formulas**:

| Page Type | Pattern | Example |
|-----------|---------|---------|
| Home | [Brand] - [Primary Service] in [Location] | Acme Plumbing - 24/7 Emergency Plumber Sydney |
| Service | [Service] in [Location] \| [Brand] | Hot Water Repairs Sydney \| Acme Plumbing |
| Location | [Service] [Suburb] \| [Brand] | Plumber Bondi \| Acme Plumbing |
| About | About [Brand] - [Tagline/USP] | About Acme - Licensed Plumbers Since 1995 |
| Contact | Contact [Brand] - [Location] \| [Phone] | Contact Acme Plumbing - Sydney \| 1300 XXX XXX |

**Title Modifiers** (add credibility):
- 24/7 Emergency
- Licensed & Insured
- Free Quotes
- Same Day Service
- Family Owned
- Award Winning

**Anti-Patterns** (avoid):
- ❌ "Welcome to..." (wastes characters)
- ❌ Keyword stuffing (plumber plumbing plumbers)
- ❌ ALL CAPS (looks spammy)
- ❌ Special characters (★ § ¶)

---

## Meta Description Patterns

**Character Limits**:
- Desktop: 155-160 characters
- Mobile: 120-130 characters

**Formula**:
[Value prop] [Service] in [Location]. [Differentiator]. [CTA].


**Examples by Page Type**:

**Home Page**:
Fast, reliable plumbing services in Sydney. 24/7 emergency response, licensed plumbers, upfront pricing. Call 1300 XXX XXX for same-day service.


**Service Page**:
Expert hot water repairs in Sydney. Fix or replace electric, gas & solar systems. Licensed technicians, 1-year warranty. Book online or call 1300 XXX XXX.


**Location Page**:
Trusted plumber in Bondi. Blocked drains, leaks, hot water, gas fitting. Same-day service, upfront quotes. Call your local plumber on 1300 XXX XXX.


**Power Words** (use sparingly):
- Trust: Licensed, Certified, Insured, Guaranteed, Trusted
- Speed: Fast, Quick, Same Day, Emergency, 24/7, Instant
- Value: Affordable, Competitive, Upfront, No Hidden Fees, Free Quote
- Local: Local, Nearby, Your Area, [Suburb Name]
- Quality: Expert, Professional, Experienced, Award Winning

---

## Open Graph Tags

**Required Tags**:

<meta property="og:title" content="Service in Location" />
<meta property="og:description" content="Value prop. Differentiator. CTA." />
<meta property="og:image" content="https://example.com/og-image.jpg" />
<meta property="og:url" content="https://example.com/page" />
<meta property="og:type" content="website" />


**Image Requirements**:
- Dimensions: 1200x630px (1.91:1 ratio)
- Format: JPG or PNG (JPG preferred for file size)
- File size: <1MB (ideally <300KB)
- Text overlay: Keep important text center (safe zone: 1000x530)

**og:type Values by Page Type**:

| Page Type | og:type |
|-----------|---------|
| Home, Service, Location | website |
| Blog Post | article |
| Business Profile | business.business |

**Optional but Recommended**:
<meta property="og:site_name" content="Brand Name" />
<meta property="og:locale" content="en_AU" />


---

## Twitter Cards

**Card Types**:

| Type | Use Case |
|------|----------|
| summary | Small square image (1:1), basic info |
| summary_large_image | Large image (1.91:1), most common |

**Required Tags**:

<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Service in Location" />
<meta name="twitter:description" content="Value prop. Differentiator. CTA." />
<meta name="twitter:image" content="https://example.com/og-image.jpg" />


**Optional**:
<meta name="twitter:site" content="@yourbrand" />
<meta name="twitter:creator" content="@authorhandle" />


**Fallback Behavior**:
- If twitter:title missing, uses og:title
- If twitter:description missing, uses og:description
- If twitter:image missing, uses og:image

**Best Practice**: Define og:* tags first, only add twitter:* if values differ.

---

## JSON-LD Structured Data

### LocalBusiness Schema (Most Important)

Use for homepage and contact page:

{
"@context": "https://schema.org",
"@type": "Plumber",
"name": "Acme Plumbing",
"description": "Licensed plumbing services in Sydney",
"@id": "https://acmeplumbing.com.au",
"url": "https://acmeplumbing.com.au",
"logo": "https://acmeplumbing.com.au/logo.png",
"image": "https://acmeplumbing.com.au/og-image.jpg",
"telephone": "+61-XXX-XXX-XXX",
"email": "[email protected]",
"priceRange": "$$",
"address": {
"@type": "PostalAddress",
"streetAddress": "123 Main Street",
"addressLocality": "Sydney",
"addressRegion": "NSW",
"postalCode": "2000",
"addressCountry": "AU"
},
"geo": {
"@type": "GeoCoordinates",
"latitude": -33.8688,
"longitude": 151.2093
},
"openingHoursSpecification": [
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
"opens": "07:00",
"closes": "17:00"
}
],
"sameAs": [
"https://facebook.com/acmeplumbing",
"https://instagram.com/acmeplumbing"
]
}


**Specific Business Types** (instead of generic LocalBusiness):
- Plumber, Electrician, Locksmith, HVAC (HVACBusiness)
- Dentist, Attorney, Accountant
- Restaurant, Cafe, FoodEstablishment
- Store, AutoRepair, BeautySalon

### Service Schema

Use for service pages:

{
"@context": "https://schema.org",
"@type": "Service",
"name": "Hot Water Repairs",
"description": "Fast hot water system repairs in Sydney",
"provider": {
"@type": "Plumber",
"name": "Acme Plumbing",
"url": "https://acmeplumbing.com.au"
},
"areaServed": {
"@type": "City",
"name": "Sydney"
},
"availableChannel": {
"@type": "ServiceChannel",
"serviceUrl": "https://acmeplumbing.com.au/hot-water-repairs",
"servicePhone": "+61-XXX-XXX-XXX"
}
}


### FAQ Schema (Rich Snippets)

Use for FAQ sections:

{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "How much does a plumber cost in Sydney?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Plumbing rates in Sydney typically range from $100-$150 per hour for standard work. Emergency callouts may incur higher rates. We provide upfront quotes before starting work."
}
},
{
"@type": "Question",
"name": "Do you offer same-day service?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes, we offer same-day plumbing service across Sydney for urgent repairs. Call us before 2pm for same-day availability."
}
}
]
}


### BreadcrumbList Schema

Use on all pages except homepage:

{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://acmeplumbing.com.au"
},
{
"@type": "ListItem",
"position": 2,
"name": "Services",
"item": "https://acmeplumbing.com.au/services"
},
{
"@type": "ListItem",
"position": 3,
"name": "Hot Water Repairs",
"item": "https://acmeplumbing.com.au/hot-water-repairs"
}
]
}


---

## Canonical URLs

**When to Use**:
- Every page should have a self-referencing canonical
- Duplicate content (pagination, filters, print versions)
- Syndicated content
- Cross-domain duplicates

**Self-Referencing Canonical**:
<!-- Always include, even if no duplicates -->
<link rel="canonical" href="https://example.com/page" />


**Pagination**:
<!-- On page 2+ -->
<link rel="canonical" href="https://example.com/services" />
<!-- Not https://example.com/services?page=2 -->


**Common Mistakes**:
- ❌ Missing canonical (Google chooses for you)
- ❌ Relative URLs (use absolute URLs)
- ❌ Canonical pointing to different content
- ❌ Multiple canonicals (only one per page)

---

## Validation Tools

**Check Your Implementation**:

| Tool | Purpose | URL |
|------|---------|-----|
| Google Rich Results Test | Test structured data | search.google.com/test/rich-results |
| Schema Markup Validator | Validate JSON-LD | validator.schema.org |
| Facebook Debugger | Test Open Graph tags | developers.facebook.com/tools/debug |
| Twitter Card Validator | Test Twitter Cards | cards-dev.twitter.com/validator |
| Screaming Frog | Audit all pages | screamingfrog.co.uk/seo-spider |

**Browser Extensions**:
- SEO Meta in 1 Click (Chrome)
- META SEO inspector (Firefox)

---

## Quick Reference Checklist

For every page, include:

- [ ] <title> (50-60 chars, unique per page)
- [ ] <meta name="description"> (150-160 chars, unique per page)
- [ ] <link rel="canonical"> (absolute URL)
- [ ] Open Graph tags (og:title, og:description, og:image, og:url, og:type)
- [ ] Twitter Card tags (twitter:card, twitter:title, twitter:description, twitter:image)
- [ ] JSON-LD structured data (LocalBusiness on homepage, Service on service pages)
- [ ] BreadcrumbList schema (all pages except homepage)
- [ ] Mobile viewport meta tag
- [ ] Charset meta tag (UTF-8)

**Never**:
- ❌ Duplicate titles across pages
- ❌ Use "Welcome to..." in titles
- ❌ Omit og:image (critical for social sharing)
- ❌ Use generic @type (LocalBusiness instead of Plumber)
- ❌ Skip CTA in meta description

---

## Error Prevention

### Common Issues

| Issue | Cause | Fix |
|-------|-------|-----|
| No rich snippets in search | Invalid JSON-LD | Use validator.schema.org, check commas/quotes |
| Social share shows wrong image | og:image missing or wrong size | Use 1200x630px, test with Facebook Debugger |
| Title truncated in search | Too long | Keep under 60 chars |
| Description truncated | Too long | Keep under 160 chars |
| Multiple pages rank for same keyword | Duplicate titles | Make each title unique |

### Testing Workflow

1. **Validate HTML**: Use W3C validator
2. **Test Structured Data**: Google Rich Results Test
3. **Test Social Sharing**: Facebook Debugger + Twitter Card Validator
4. **Mobile Preview**: Google Search Console URL Inspection
5. **Cross-Browser Check**: Test meta rendering in Chrome/Firefox/Safari

---

## Best Practices Summary

**Title Tags**:
- 50-60 characters maximum
- Include primary keyword + location + brand
- Unique for every page
- Use modifiers (24/7, Licensed, Free) sparingly

**Meta Descriptions**:
- 150-160 characters maximum
- Include value prop + differentiator + CTA
- Write for humans, not search engines
- Every page needs unique description

**Open Graph**:
- Always include og:image (1200x630px)
- Use absolute URLs
- Keep og:title under 60 chars
- Test with Facebook Debugger before launch

**JSON-LD**:
- Use specific @type (Plumber, not LocalBusiness)
- Include all contact info (phone, address, email)
- Add openingHoursSpecification for better display
- Validate with schema.org validator

**Canonical URLs**:
- Every page needs canonical
- Always use absolute URLs
- Self-referencing is good practice
- Only one canonical per page

---

**Production Notes**:
- Use react-helmet-async for React apps (SSR-safe)
- Generate JSON-LD dynamically from CMS/database
- Cache meta tag components for performance
- Monitor Search Console for indexing issues
- Update structured data when business details change


---

# SEO Meta Tags Corrections

## Title Tag Patterns

| If Claude suggests... | Use instead... |
|----------------------|----------------|
| "Welcome to [Brand]" in title | Start with service/value prop |
| Title >60 characters | Keep under 60 chars for full display |
| Same title on multiple pages | Unique title per page |
| Generic "Home" or "Services" | Specific: "Emergency Plumber Sydney \| Brand" |
| ALL CAPS title | Title case (first letter caps) |

## Meta Description Patterns

| If Claude suggests... | Use instead... |
|----------------------|----------------|
| Description >160 characters | Keep 150-160 chars (desktop), 120-130 (mobile) |
| No call to action | End with CTA: "Call 1300 XXX XXX" or "Book online" |
| Same description on all pages | Unique description per page |
| Keyword stuffing | Natural language with 1-2 keywords |
| No differentiator | Include USP: "24/7 service", "upfront pricing" |

## Open Graph Tags

| If Claude suggests... | Use instead... |
|----------------------|----------------|
| Missing og:image | Always include og:image (1200x630px) |
| Relative URL in og:image | Absolute URL: "https://example.com/og-image.jpg" |
| Wrong image size | 1200x630px (1.91:1 ratio) |
| Missing og:type | Include: "website" (pages) or "article" (blog) |
| Different og:url and canonical | Match og:url to canonical tag |

## JSON-LD Structured Data

| If Claude suggests... | Use instead... |
|----------------------|----------------|
| Generic @type "LocalBusiness" | Specific: "Plumber", "Electrician", "Locksmith" |
| Missing required fields | Include: name, @id, url, address, telephone |
| Relative URLs in schema | Absolute URLs starting with https:// |
| Date format "DD/MM/YYYY" | ISO 8601: "2026-01-14T10:00:00+11:00" |
| Missing @context | Always include: "@context": "https://schema.org" |

## Canonical URLs

| If Claude suggests... | Use instead... |
|----------------------|----------------|
| No canonical tag | Every page needs self-referencing canonical |
| Relative URL in canonical | Absolute URL: "https://example.com/page" |
| Multiple canonical tags | Only one canonical per page |
| Canonical to redirect | Point directly to final destination |
| Canonical with query parameters | Strip params: /page not /page?ref=nav |

## Common Anti-Patterns

| Anti-Pattern | Why It's Wrong | Correct Pattern |
|--------------|----------------|-----------------|
| "Welcome to..." in title | Wastes 11 characters | Start with service/value |
| Emoji in title/description | Breaks in search results | Use text only |
| Keyword stuffing | Looks spammy, hurts ranking | Natural language, 1-2 mentions |
| Missing og:image | Breaks social sharing | Always include (1200x630px) |
| Generic schema @type | Doesn't help SEO | Use specific type (Plumber not LocalBusiness) |
| Duplicate titles | Confuses search engines | Unique title per page |
| Description without CTA | Missed opportunity | End with clear CTA |

## Page Type Patterns

### Homepage

// Title Pattern
"[Brand] - [Primary Service] in [Location]"
// Example: Acme Plumbing - 24/7 Emergency Plumber Sydney

// Description Pattern
"[Value prop] [Service] in [Location]. [Differentiator]. [CTA]."
// Example: Fast, reliable plumbing services in Sydney. 24/7 emergency response, licensed plumbers, upfront pricing. Call 1300 XXX XXX for same-day service.

// Schema
@type: "Plumber" (specific, not LocalBusiness)


### Service Page

// Title Pattern
"[Service] in [Location] | [Brand]"
// Example: Hot Water Repairs Sydney | Acme Plumbing

// Description Pattern
"[Specific Service] in [Location]. [Service Details]. [Differentiator]. [CTA]."
// Example: Expert hot water repairs in Sydney. Fix or replace electric, gas & solar systems. Licensed technicians, 1-year warranty. Book online or call 1300 XXX XXX.

// Schema
@type: "Service"
Include: provider, areaServed, availableChannel


### Location Page

// Title Pattern
"[Service] [Suburb] | [Brand]"
// Example: Plumber Bondi | Acme Plumbing

// Description Pattern
"[Service] in [Suburb]. [Service Types]. [Differentiator]. [Local CTA]."
// Example: Trusted plumber in Bondi. Blocked drains, leaks, hot water, gas fitting. Same-day service, upfront quotes. Call your local plumber on 1300 XXX XXX.


## Character Limits Quick Reference

| Element | Desktop | Mobile | Best Practice |
|---------|---------|--------|---------------|
| Title | 50-60 chars | ~78 chars | Keep under 60 |
| Meta Description | 155-160 chars | 120-130 chars | 150-160, front-load key info |
| og:title | 60-70 chars | Varies | Match page title or shorter |
| og:description | 200-300 chars | Varies | Can be longer than meta |
| twitter:title | 70 chars | Same | Can match OG or shorter |

## Validation Checklist

Before deploying, verify:

- [ ] Title is unique and <60 characters
- [ ] Description is unique and 150-160 characters
- [ ] Description includes CTA
- [ ] Canonical tag present (absolute URL)
- [ ] og:image present (1200x630px, absolute URL)
- [ ] og:url matches canonical
- [ ] JSON-LD has specific @type (not generic)
- [ ] JSON-LD has all required fields
- [ ] All URLs are absolute (https://)
- [ ] No duplicate titles across pages
- [ ] No "Welcome to..." in title
- [ ] Tested with Google Rich Results Test
- [ ] Tested with Facebook Debugger

## Testing Tools

| Tool | Use For | URL |
|------|---------|-----|
| Google Rich Results Test | Validate JSON-LD | search.google.com/test/rich-results |
| Schema Markup Validator | Validate schema syntax | validator.schema.org |
| Facebook Debugger | Test Open Graph | developers.facebook.com/tools/debug |
| Twitter Card Validator | Test Twitter Cards | cards-dev.twitter.com/validator |

## Production Workflow

1. **Generate meta tags** from CMS/database (never hardcode)
2. **Validate** with Rich Results Test before deploying
3. **Test social sharing** with Facebook/Twitter debuggers
4. **Monitor** Search Console for indexing issues
5. **Update** when business details change (hours, phone, services)

---

**Source**: Schema.org, Open Graph Protocol, Google Search Central

How to Use This Skill Unit

Option A: Project-Specific (Recommended)

  1. Click "Download" above
  2. In your project, create the directory: .agent/skills/seo-meta/
  3. Save the file as SKILL.md
  4. The agent will automatically discover the skill based on its description.

Option B: Global Installation (All Agents)

Save the file to these locations to make it available across all projects:

  • Claude Code: ~/.claude/skills/jezweb/claude-skills/seo-meta/SKILL.md
  • Cursor: ~/.cursor/skills/jezweb/claude-skills/seo-meta/SKILL.md
  • Antigravity: ~/.gemini/antigravity/skills/jezweb/claude-skills/seo-meta/SKILL.md

🚀 Install with CLI:
npx skills add jezweb/claude-skills

Read the Master Guide: Mastering Agent Skills

Related Skill Units

Recommended Rules

View more rules

Recommended Workflows

View more workflows

Recommended MCP Servers

View more MCP servers

Take It Further

Maximize your productivity with these powerful resources

📋

Define Your Standards

Set up coding standards to ensure this workflow produces consistent, high-quality results.

Browse Rules Library
📖

Master Workflows

Learn how to create custom workflows, use Turbo Mode, and build your automation library.

Complete Guide

How to use this Skill in Claude Code & Cursor

For Claude Code (CLI)

To use this skill in Claude Code, copy the rule content into your project's custom instructions or follow our Add-Skill CLI guide. This ensures Claude follows your standards during every code generation.

For Cursor & Windsurf

For Cursor or Windsurf, individual skills are best used in the "Rules for AI" section. This specific unit helps the agent avoid seo issues, leading to cleaner, more efficient code.

Why the skill format matters: the standardized Agent Skills format lets your AI agent load detailed instructions only when they are relevant, keeping your prompt clean while improving results.

Source & attribution

This skill is categorized under Seo and is published by JezWeb, maintained in jezweb/claude-skills.

← Browse All Agent Skills
Sponsored AI assistant. Recommendations may be paid.