Skill do Especialista SEO para otimização de páginas e sistemas para motores de busca. Use quando precisar otimizar meta tags, Open Graph, sitemap, schema markup, Core Web Vitals, performance, imagens, fontes, acessibilidade para SEO, ou qualquer decisão de ranqueamento. Trigger em: "SEO", "meta tags", "Open Graph", "sitemap", "schema markup", "Core Web Vitals", "performance", "LCP", "CLS", "ranking", "canonical", "robots.txt".
86
Quality
82%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Passed
No known issues
O Especialista SEO é responsável por garantir que o sistema e landing pages sejam encontráveis, rápidos e bem ranqueados nos motores de busca.
Esta skill segue GLOBAL.md, policies/execution.md, policies/handoffs.md, policies/quality-gates.md, policies/token-efficiency.md, policies/stack-flexibility.md, policies/evals.md e policies/tool-safety.md.
Para templates de metadata, schema e checks de indexacao, consultar docs/skill-guides/seo-specialist.md apenas quando necessario.
src/app/layout.tsx
import type { Metadata } from 'next';
export function generateMetadata({
title,
description,
url,
image,
}: {
title: string;
description: string;
url: string;
image?: string;
}): Metadata {
const siteName = 'Nome do Projeto';
const defaultImage = '/og-image.png';
return {
title: {
default: title,
template: `%s | ${siteName}`,
},
description,
alternates: {
canonical: url,
},
openGraph: {
title,
description,
url,
siteName,
images: [
{
url: image || defaultImage,
width: 1200,
height: 630,
alt: title,
},
],
locale: 'pt_BR',
type: 'website',
},
twitter: {
card: 'summary_large_image',
title,
description,
images: [image || defaultImage],
},
robots: {
index: true,
follow: true,
googleBot: {
index: true,
follow: true,
'max-video-preview': -1,
'max-image-preview': 'large',
'max-snippet': -1,
},
},
};
}src/components/seo/WebsiteSchema.tsx
export function WebsiteSchema({ url, name }: { url: string; name: string }) {
const schema = {
'@context': 'https://schema.org',
'@type': 'WebSite',
name,
url,
potentialAction: {
'@type': 'SearchAction',
target: `${url}/search?q={search_term_string}`,
'query-input': 'required name=search_term_string',
},
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}src/components/seo/OrganizationSchema.tsx
export function OrganizationSchema({
name,
url,
logo,
sameAs,
}: {
name: string;
url: string;
logo: string;
sameAs: string[];
}) {
const schema = {
'@context': 'https://schema.org',
'@type': 'Organization',
name,
url,
logo,
sameAs,
contactPoint: {
'@type': 'ContactPoint',
contactType: 'customer service',
availableLanguage: ['Portuguese'],
},
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}src/components/seo/FAQSchema.tsx
interface FAQItem {
question: string;
answer: string;
}
export function FAQSchema({ items }: { items: FAQItem[] }) {
const schema = {
'@context': 'https://schema.org',
'@type': 'FAQPage',
mainEntity: items.map((item) => ({
'@type': 'Question',
name: item.question,
acceptedAnswer: {
'@type': 'Answer',
text: item.answer,
},
})),
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}Métrica Alvo Descrição
─────────────────────────────────────────────────────────────
LCP < 2.5s Largest Contentful Paint — tempo até o maior elemento visível
FID < 100ms First Input Delay — tempo de resposta à primeira interação
CLS < 0.1 Cumulative Layout Shift — estabilidade visual da página
INP < 200ms Interaction to Next Paint — responsividade geral
TTFB < 800ms Time to First Byte — velocidade do servidorTodas as métricas devem estar na zona verde do Google PageSpeed Insights.
next.config.js
const nextConfig = {
images: {
formats: ['image/avif', 'image/webp'],
},
experimental: {
optimizeCss: true,
},
compress: true,
poweredByHeader: false,
};
module.exports = nextConfig;Regras inegociáveis:
next/image — nunca <img> nativowidth e height) em todas as imagenspriority para imagens hero (above the fold)src/components/ui/OptimizedImage.tsx
import Image from 'next/image';
interface OptimizedImageProps {
src: string;
alt: string;
width: number;
height: number;
priority?: boolean;
className?: string;
}
export function OptimizedImage({
src,
alt,
width,
height,
priority = false,
className,
}: OptimizedImageProps) {
return (
<Image
src={src}
alt={alt}
width={width}
height={height}
priority={priority}
loading={priority ? 'eager' : 'lazy'}
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
className={className}
/>
);
}next/font (self-hosted, zero CLS)font-display: swap obrigatóriosrc/app/layout.tsx
import { Inter } from 'next/font/google';
const inter = Inter({
subsets: ['latin'],
display: 'swap',
variable: '--font-inter',
});
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="pt-BR" className={inter.variable}>
<body>{children}</body>
</html>
);
}loading="lazy" em imagens e iframes fora da viewportsrc/app/page.tsx
import dynamic from 'next/dynamic';
const FAQ = dynamic(() => import('@/components/sections/FAQ'));
const Testimonials = dynamic(() => import('@/components/sections/Testimonials'));
const Footer = dynamic(() => import('@/components/layout/Footer'));src/components/ThirdPartyScripts.tsx
import Script from 'next/script';
export function ThirdPartyScripts() {
return (
<>
<Script
src="https://www.googletagmanager.com/gtag/js?id=G-XXXXX"
strategy="afterInteractive"
/>
<Script id="gtag-init" strategy="afterInteractive">
{`window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXX');`}
</Script>
</>
);
}Correto Errado
──────────────────────────────────────────
<header> <div class="header">
<nav> <div class="nav">
<main> <div class="main">
<section> <div class="section">
<article> <div class="article">
<aside> <div class="sidebar">
<footer> <div class="footer">
<h1> a <h6> <div class="title">
<figure> + <figcaption> <div class="image-wrapper">
<time datetime=""> <span class="date">
<address> <div class="contact">
<mark> <span class="highlight">Regras:
<h1> por página<main> uma única vez por página<nav> com aria-label quando houver mais de uma navegaçãoMeta descriptions: SEO NAO reescreve o copy — apenas otimiza formato, keywords e tamanho. Se o texto precisa mudar substancialmente, devolver pro Copy.
Comentarios no codigo so fazem sentido quando explicam contexto nao obvio, restricoes externas ou workarounds temporarios. O padrao continua sendo codigo claro com nomes descritivos.
524725e
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.