Saltar al contenido principal

🔍 Herramienta Análisis SEO

SaaS de análisis SEO con IA para optimizar contenido web.

📋 Contexto​

Las herramientas SEO existentes son complejas. Esta solución ofrece análisis instantáneo con sugerencias de IA.

🎯 Objetivo​

Construir SaaS que permita:

  • Analizar contenido HTML/URL
  • Calcular métricas SEO (densidad, legibilidad)
  • Generar sugerencias con OpenAI
  • Historial de análisis por usuario

📦 Alcance​

Incluye:

  • Análisis SEO automático
  • Puntuación 0-100
  • Sugerencias IA
  • Dashboard con historial

Stack:

  • Next.js 14 + TypeScript
  • Tailwind + shadcn/ui
  • Clerk Auth
  • Neon PostgreSQL + Prisma
  • OpenAI API

🏛️ Arquitectura​

Estructura​

/app
/api
/analyze/route.ts
/ai-suggestions/route.ts
/dashboard/page.tsx
/analyze/page.tsx

/components
/analysis-form.tsx
/seo-results.tsx
/ai-suggestions.tsx

/lib
/seo-analyzer.ts
/readability.ts
/openai.ts

🗄️ Base de Datos​

Schema Prisma​

model User {
id String @id @default(cuid())
clerkId String @unique
email String @unique
trialEndsAt DateTime?
isPro Boolean @default(false)
analyses Analysis[]
}

model Analysis {
id String @id @default(cuid())
userId String
user User @relation(fields: [userId], references: [id])

content String @db.Text
keyword String
url String?

// Métricas
wordCount Int
keywordDensity Float
readabilityScore Float
seoScore Int

// Estructura
hasH1 Boolean
h1Text String?
headings Json // {h2: [], h3: []}
images Int
imagesWithoutAlt Int
internalLinks Int
externalLinks Int

// Meta
metaTitle String?
metaDescription String?
aiSuggestions Json?

createdAt DateTime @default(now())

@@index([userId])
}

🔍 Lógica SEO​

Analyzer Core​

interface SEOAnalysis {
wordCount: number;
keywordDensity: number;
hasH1: boolean;
h1Text: string | null;
headings: { h2: string[]; h3: string[] };
images: number;
imagesWithoutAlt: number;
internalLinks: number;
externalLinks: number;
keywordInTitle: boolean;
keywordInFirst150: boolean;
seoScore: number;
}

export function analyzeSEO(html: string, keyword: string): SEOAnalysis {
const doc = new DOMParser().parseFromString(html, "text/html");
const text = doc.body.textContent || "";
const words = text
.toLowerCase()
.split(/\s+/)
.filter(w => w.length > 0);

const keywordLower = keyword.toLowerCase();
const keywordCount = words.filter(w => w.includes(keywordLower)).length;

// Cálculo de score
let score = 0;
if (words.length >= 800) score += 20;
if (keywordDensity >= 0.5 && keywordDensity <= 2.5) score += 20;
if (h1) score += 15;
if (keywordInH1) score += 15;

return {
/* ... */
};
}

🎯 Score SEO​

FactorPesoCondición
Longitud contenido20%≥800 palabras
Densidad keyword20%0.5% - 2.5%
H1 presente15%Debe existir
Keyword en H115%Coincidencia
Keyword en primer 150 chars10%Posición inicial
Imágenes con alt10%100% cobertura
Links externos10%>0

✅ Checklist Implementación​

  • Schema Prisma creado
  • Migraciones aplicadas
  • API /analyze funcionando
  • Score calculado correctamente
  • UI con shadcn/ui
  • Clerk auth integrado
  • OpenAI sugerencias

📚 Referencias​