feat: Implement comprehensive AI-era SEO optimizations
- Add llms.txt file for AI crawlers (llmstxt.org standard) - Enhance robots.txt with 15+ AI bot rules (GPTBot, ClaudeBot, etc.) - Expand JSON-LD structured data from 1 to 12+ schema blocks: - Person (enhanced with occupations, languages, employers) - WebSite, BreadcrumbList, ProfilePage - EducationalOccupationalCredential (dynamic per education) - Course (dynamic per certification) - Create doc/15-SEO.md with comprehensive SEO documentation - Update MODERN-WEB-TECHNIQUES.md with SEO section (techniques 11-13) Based on WPBeginner 2025 SEO recommendations for AI Overviews, structured data, and E-E-A-T signals.
This commit is contained in:
+314
@@ -0,0 +1,314 @@
|
|||||||
|
# SEO Implementation Guide
|
||||||
|
|
||||||
|
**Project:** CV Interactive Website
|
||||||
|
**Last Updated:** 2025-11-30
|
||||||
|
**Status:** Production Ready
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This document describes the comprehensive SEO (Search Engine Optimization) implementation for the CV website, including traditional search engine optimization and modern AI-era optimizations for LLM crawlers and AI Overviews.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SEO Architecture
|
||||||
|
|
||||||
|
### 1. Traditional SEO Elements
|
||||||
|
|
||||||
|
#### Meta Tags (`templates/index.html`)
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- Primary Meta Tags -->
|
||||||
|
<title>{{.CV.Personal.Name}} - {{.CV.SEO.PageTitle}}</title>
|
||||||
|
<meta name="title" content="...">
|
||||||
|
<meta name="description" content="...">
|
||||||
|
<meta name="keywords" content="...">
|
||||||
|
<meta name="author" content="...">
|
||||||
|
<meta name="robots" content="index, follow">
|
||||||
|
<link rel="canonical" href="{{.CanonicalURL}}">
|
||||||
|
```
|
||||||
|
|
||||||
|
#### International SEO (Hreflang)
|
||||||
|
|
||||||
|
```html
|
||||||
|
<link rel="alternate" hreflang="en" href="{{.AlternateEN}}">
|
||||||
|
<link rel="alternate" hreflang="es" href="{{.AlternateES}}">
|
||||||
|
<link rel="alternate" hreflang="x-default" href="https://juan.andres.morenorub.io/?lang=en">
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Social Media Integration
|
||||||
|
|
||||||
|
| Platform | Meta Type | Implementation |
|
||||||
|
|----------|-----------|----------------|
|
||||||
|
| Facebook | Open Graph | `og:type`, `og:title`, `og:description`, `og:image` |
|
||||||
|
| Twitter/X | Twitter Cards | `twitter:card`, `twitter:title`, `twitter:description` |
|
||||||
|
| LinkedIn | Open Graph | Uses same `og:*` tags |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. Structured Data (JSON-LD)
|
||||||
|
|
||||||
|
The site implements multiple Schema.org types for comprehensive semantic understanding:
|
||||||
|
|
||||||
|
#### Person Schema (Primary)
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@type": "Person",
|
||||||
|
"@id": "{{.CV.Personal.Website}}/#person",
|
||||||
|
"name": "...",
|
||||||
|
"jobTitle": "...",
|
||||||
|
"description": "...",
|
||||||
|
"knowsAbout": [...],
|
||||||
|
"knowsLanguage": [...],
|
||||||
|
"worksFor": [...],
|
||||||
|
"hasOccupation": [...]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Fields included:**
|
||||||
|
- Basic info: name, givenName, familyName, jobTitle
|
||||||
|
- Contact: email, telephone, url
|
||||||
|
- Demographics: birthDate, birthPlace, nationality
|
||||||
|
- Location: address with locality and country
|
||||||
|
- Social: sameAs (LinkedIn, GitHub, Domestika)
|
||||||
|
- Education: alumniOf
|
||||||
|
- Skills: knowsAbout (array of expertise areas)
|
||||||
|
- Languages: knowsLanguage (with Language type)
|
||||||
|
- Employment: worksFor (multiple organizations)
|
||||||
|
- Occupations: hasOccupation (dynamically generated from experience)
|
||||||
|
|
||||||
|
#### WebSite Schema
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@type": "WebSite",
|
||||||
|
"name": "... - Professional CV",
|
||||||
|
"url": "...",
|
||||||
|
"inLanguage": ["en", "es"],
|
||||||
|
"potentialAction": { "@type": "SearchAction", ... }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### BreadcrumbList Schema
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@type": "BreadcrumbList",
|
||||||
|
"itemListElement": [
|
||||||
|
{ "position": 1, "name": "Home", "item": "..." },
|
||||||
|
{ "position": 2, "name": "CV (English/Español)", "item": ".../?lang=..." }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### ProfilePage Schema
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@type": "ProfilePage",
|
||||||
|
"mainEntity": { "@id": ".../#person" },
|
||||||
|
"dateCreated": "...",
|
||||||
|
"dateModified": "...",
|
||||||
|
"inLanguage": "..."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### EducationalOccupationalCredential Schema
|
||||||
|
Generated dynamically for each education entry:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@type": "EducationalOccupationalCredential",
|
||||||
|
"name": "{{.Degree}}",
|
||||||
|
"description": "{{.Field}}",
|
||||||
|
"educationalLevel": "Bachelor's Degree",
|
||||||
|
"credentialCategory": "degree",
|
||||||
|
"recognizedBy": { "@type": "CollegeOrUniversity", ... }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Course Schema
|
||||||
|
Generated dynamically for each course/certification:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@type": "Course",
|
||||||
|
"name": "{{.Title}}",
|
||||||
|
"description": "...",
|
||||||
|
"provider": { "@type": "Organization", ... },
|
||||||
|
"hasCourseInstance": { "@type": "CourseInstance", ... },
|
||||||
|
"timeRequired": "{{.Duration}}"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. AI-Era SEO Optimizations
|
||||||
|
|
||||||
|
#### llms.txt File (`static/llms.txt`)
|
||||||
|
|
||||||
|
A dedicated file for AI crawlers following the [llmstxt.org](https://llmstxt.org/) standard:
|
||||||
|
|
||||||
|
```
|
||||||
|
# llms.txt - AI Crawler Information
|
||||||
|
name: Juan Andrés Moreno Rubio - Professional CV
|
||||||
|
description: Interactive curriculum vitae...
|
||||||
|
|
||||||
|
## Professional Summary
|
||||||
|
- Senior Technical Consultant...
|
||||||
|
|
||||||
|
## Key Expertise
|
||||||
|
- SAP Customer Data Cloud...
|
||||||
|
|
||||||
|
## Contact
|
||||||
|
- Website: ...
|
||||||
|
- LinkedIn: ...
|
||||||
|
```
|
||||||
|
|
||||||
|
**Purpose:** Provides AI systems (ChatGPT, Claude, Perplexity, etc.) with structured, human-readable information about the site content.
|
||||||
|
|
||||||
|
#### robots.txt AI Bot Rules (`static/robots.txt`)
|
||||||
|
|
||||||
|
Explicit permissions for AI crawlers:
|
||||||
|
|
||||||
|
| Bot | Service | Status |
|
||||||
|
|-----|---------|--------|
|
||||||
|
| GPTBot | OpenAI/ChatGPT | Allowed |
|
||||||
|
| ChatGPT-User | OpenAI | Allowed |
|
||||||
|
| ClaudeBot | Anthropic | Allowed |
|
||||||
|
| Claude-Web | Anthropic | Allowed |
|
||||||
|
| anthropic-ai | Anthropic | Allowed |
|
||||||
|
| Google-Extended | Google AI/Gemini | Allowed |
|
||||||
|
| PerplexityBot | Perplexity AI | Allowed |
|
||||||
|
| cohere-ai | Cohere | Allowed |
|
||||||
|
| CCBot | Common Crawl | Allowed |
|
||||||
|
| Amazonbot | Amazon/Alexa | Allowed |
|
||||||
|
| Applebot | Apple/Siri | Allowed |
|
||||||
|
| Copilot | Microsoft | Allowed |
|
||||||
|
| YouBot | You.com | Allowed |
|
||||||
|
| BraveBot | Brave Search | Allowed |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## E-E-A-T Signals
|
||||||
|
|
||||||
|
The implementation supports Google's E-E-A-T (Experience, Expertise, Authority, Trust) framework:
|
||||||
|
|
||||||
|
### Experience
|
||||||
|
- Detailed work history with responsibilities
|
||||||
|
- Real project descriptions
|
||||||
|
- Duration and dates for credibility
|
||||||
|
|
||||||
|
### Expertise
|
||||||
|
- Skills categorized by domain
|
||||||
|
- Technologies listed per job
|
||||||
|
- Certifications and courses
|
||||||
|
|
||||||
|
### Authority
|
||||||
|
- Links to LinkedIn, GitHub, portfolio
|
||||||
|
- Company associations (SAP, Olympic Broadcasting)
|
||||||
|
- Client count and project metrics in summary
|
||||||
|
|
||||||
|
### Trust
|
||||||
|
- Canonical URLs prevent duplicate content
|
||||||
|
- HTTPS enforced
|
||||||
|
- Clear contact information
|
||||||
|
- Privacy-respecting analytics (Matomo)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Files Overview
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| `templates/index.html` | Meta tags, JSON-LD schemas |
|
||||||
|
| `static/robots.txt` | Search engine and AI bot directives |
|
||||||
|
| `static/llms.txt` | AI crawler information file |
|
||||||
|
| `static/sitemap.xml` | XML sitemap for search engines |
|
||||||
|
| `data/cv-en.json` | SEO fields (pageTitle, metaTitle, etc.) |
|
||||||
|
| `data/cv-es.json` | Spanish SEO fields |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SEO Data Model
|
||||||
|
|
||||||
|
The SEO-specific fields in `data/cv-{lang}.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"seo": {
|
||||||
|
"pageTitle": "Curriculum Vitae",
|
||||||
|
"metaTitle": "Professional CV",
|
||||||
|
"metaDescription": "18 years of experience in...",
|
||||||
|
"ogDescription": "Senior Technical Consultant...",
|
||||||
|
"keywords": "CV, Resume, FullStack Developer, SAP CDC..."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Validation & Testing
|
||||||
|
|
||||||
|
### Schema Validation
|
||||||
|
Test structured data at:
|
||||||
|
- [Google Rich Results Test](https://search.google.com/test/rich-results)
|
||||||
|
- [Schema.org Validator](https://validator.schema.org/)
|
||||||
|
|
||||||
|
### Expected Schema Count
|
||||||
|
The site generates **12+ JSON-LD blocks**:
|
||||||
|
- 1 Person schema
|
||||||
|
- 1 WebSite schema
|
||||||
|
- 1 BreadcrumbList schema
|
||||||
|
- 1 ProfilePage schema
|
||||||
|
- N EducationalOccupationalCredential schemas (1 per education)
|
||||||
|
- N Course schemas (1 per course)
|
||||||
|
|
||||||
|
### robots.txt Validation
|
||||||
|
Test at: [Google Robots.txt Tester](https://www.google.com/webmasters/tools/robots-testing-tool)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Best Practices Implemented
|
||||||
|
|
||||||
|
### Content Structure
|
||||||
|
- [ ] Clear H1-H6 heading hierarchy
|
||||||
|
- [x] Semantic HTML5 elements (article, section, nav)
|
||||||
|
- [x] Alt text for images
|
||||||
|
- [x] Descriptive link text
|
||||||
|
|
||||||
|
### Technical SEO
|
||||||
|
- [x] Mobile-responsive design
|
||||||
|
- [x] Fast page load (bundled CSS, preload fonts)
|
||||||
|
- [x] Canonical URLs
|
||||||
|
- [x] Hreflang for multilingual
|
||||||
|
- [x] Sitemap.xml
|
||||||
|
- [x] robots.txt with AI bot rules
|
||||||
|
|
||||||
|
### Modern SEO (AI-Era)
|
||||||
|
- [x] llms.txt file
|
||||||
|
- [x] Comprehensive JSON-LD schemas
|
||||||
|
- [x] AI bot permissions in robots.txt
|
||||||
|
- [x] Clear, parseable content structure
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Maintenance
|
||||||
|
|
||||||
|
### When to Update
|
||||||
|
|
||||||
|
1. **Content changes**: Update `data/cv-{lang}.json` SEO fields
|
||||||
|
2. **New sections**: Add corresponding Schema.org types
|
||||||
|
3. **New AI bots**: Add to `robots.txt`
|
||||||
|
4. **Annual review**: Update `llms.txt` with current info
|
||||||
|
|
||||||
|
### Monitoring
|
||||||
|
|
||||||
|
- Google Search Console for traditional SEO
|
||||||
|
- Matomo Analytics for traffic patterns
|
||||||
|
- Manual testing in AI chat interfaces (ChatGPT, Claude, Perplexity)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [Schema.org](https://schema.org/)
|
||||||
|
- [Google Search Central](https://developers.google.com/search)
|
||||||
|
- [llmstxt.org Standard](https://llmstxt.org/)
|
||||||
|
- [WPBeginner SEO Guide 2025](https://www.wpbeginner.com/opinion/does-seo-still-work/)
|
||||||
@@ -3409,4 +3409,147 @@ make css-clean # Remove generated bundles
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*This document serves as both a technical reference and a demonstration of modern web development practices that prioritize web standards, performance, progressive enhancement, and superior user experience over JavaScript-heavy solutions.*
|
## 🔍 SEO & AI-Era Optimization (2025)
|
||||||
|
|
||||||
|
### The Challenge
|
||||||
|
|
||||||
|
Traditional SEO focused on keywords and backlinks. Modern SEO must optimize for:
|
||||||
|
1. **AI Overviews** - Content appearing in generative AI summaries
|
||||||
|
2. **LLM Crawlers** - ChatGPT, Claude, Perplexity bots
|
||||||
|
3. **Structured Data** - Schema.org for semantic understanding
|
||||||
|
4. **E-E-A-T** - Experience, Expertise, Authority, Trust signals
|
||||||
|
|
||||||
|
### Implementation
|
||||||
|
|
||||||
|
#### 11. Comprehensive Schema.org Structured Data
|
||||||
|
|
||||||
|
**Problem:** Single JSON-LD schema only described the person, not the content structure.
|
||||||
|
|
||||||
|
**Solution:** Multiple interconnected Schema.org types:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- Person Schema (primary) -->
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@type": "Person",
|
||||||
|
"@id": "{{.Website}}/#person",
|
||||||
|
"name": "...",
|
||||||
|
"hasOccupation": [...], // Dynamic from experience
|
||||||
|
"knowsLanguage": [...],
|
||||||
|
"worksFor": [...]
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- WebSite Schema -->
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@type": "WebSite",
|
||||||
|
"author": { "@id": ".../#person" } // Links to Person
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- BreadcrumbList, ProfilePage, Course, EducationalOccupationalCredential... -->
|
||||||
|
```
|
||||||
|
|
||||||
|
**Schemas implemented:**
|
||||||
|
| Schema Type | Purpose | Dynamic |
|
||||||
|
|-------------|---------|---------|
|
||||||
|
| Person | Primary profile | Yes (from CV data) |
|
||||||
|
| WebSite | Site metadata | No |
|
||||||
|
| BreadcrumbList | Navigation structure | Yes (language-aware) |
|
||||||
|
| ProfilePage | CV page metadata | Yes |
|
||||||
|
| EducationalOccupationalCredential | Education entries | Yes (loop) |
|
||||||
|
| Course | Certifications/training | Yes (loop) |
|
||||||
|
| Occupation | Work experience | Yes (embedded in Person) |
|
||||||
|
|
||||||
|
**Result:** 12+ JSON-LD blocks providing comprehensive semantic data for search engines and AI.
|
||||||
|
|
||||||
|
#### 12. llms.txt - AI Crawler Information File
|
||||||
|
|
||||||
|
**Problem:** AI systems (ChatGPT, Claude, Perplexity) need structured access to site content.
|
||||||
|
|
||||||
|
**Solution:** Implement [llmstxt.org](https://llmstxt.org/) standard:
|
||||||
|
|
||||||
|
```
|
||||||
|
# static/llms.txt
|
||||||
|
name: Juan Andrés Moreno Rubio - Professional CV
|
||||||
|
description: Interactive curriculum vitae...
|
||||||
|
|
||||||
|
## Professional Summary
|
||||||
|
- Senior Technical Consultant...
|
||||||
|
|
||||||
|
## Key Expertise
|
||||||
|
- SAP Customer Data Cloud...
|
||||||
|
|
||||||
|
## Contact
|
||||||
|
- Website: ...
|
||||||
|
```
|
||||||
|
|
||||||
|
**Purpose:** Provides AI systems with human-readable, structured information about the site—optimized for RAG (Retrieval-Augmented Generation) systems.
|
||||||
|
|
||||||
|
#### 13. robots.txt AI Bot Rules
|
||||||
|
|
||||||
|
**Problem:** AI bots weren't explicitly permitted, potentially missing from training data.
|
||||||
|
|
||||||
|
**Solution:** Comprehensive AI crawler permissions:
|
||||||
|
|
||||||
|
```txt
|
||||||
|
# static/robots.txt
|
||||||
|
|
||||||
|
# Traditional Search Engines
|
||||||
|
User-agent: Googlebot
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
# AI Crawlers - Explicitly Allowed
|
||||||
|
User-agent: GPTBot # OpenAI
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
User-agent: ClaudeBot # Anthropic
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
User-agent: PerplexityBot # Perplexity AI
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
User-agent: Google-Extended # Google AI/Gemini
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
# ... 15+ AI bot rules
|
||||||
|
```
|
||||||
|
|
||||||
|
**Bots covered:**
|
||||||
|
- OpenAI (GPTBot, ChatGPT-User)
|
||||||
|
- Anthropic (ClaudeBot, Claude-Web, anthropic-ai)
|
||||||
|
- Google (Google-Extended)
|
||||||
|
- Meta (FacebookBot, Meta-ExternalAgent)
|
||||||
|
- Perplexity, Cohere, Amazon, Apple, Microsoft, You.com, Brave
|
||||||
|
|
||||||
|
### E-E-A-T Signal Implementation
|
||||||
|
|
||||||
|
| Signal | Implementation |
|
||||||
|
|--------|----------------|
|
||||||
|
| **Experience** | Detailed work history with dates, responsibilities, technologies |
|
||||||
|
| **Expertise** | Skills categorization, certifications, course completions |
|
||||||
|
| **Authority** | Social links (LinkedIn, GitHub), company associations |
|
||||||
|
| **Trust** | HTTPS, canonical URLs, clear contact info, privacy-respecting analytics |
|
||||||
|
|
||||||
|
### SEO Files Overview
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| `templates/index.html` | Meta tags, JSON-LD schemas |
|
||||||
|
| `static/robots.txt` | Search engine + AI bot directives |
|
||||||
|
| `static/llms.txt` | AI crawler information file |
|
||||||
|
| `static/sitemap.xml` | XML sitemap |
|
||||||
|
| `data/cv-{lang}.json` | SEO fields per language |
|
||||||
|
|
||||||
|
### Validation
|
||||||
|
|
||||||
|
Test structured data:
|
||||||
|
- [Google Rich Results Test](https://search.google.com/test/rich-results)
|
||||||
|
- [Schema.org Validator](https://validator.schema.org/)
|
||||||
|
|
||||||
|
**Full documentation:** See `doc/15-SEO.md`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*This document serves as both a technical reference and a demonstration of modern web development practices that prioritize web standards, performance, progressive enhancement, AI-era SEO, and superior user experience over JavaScript-heavy solutions.*
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
# llms.txt - AI Crawler Information for juan.andres.morenorub.io
|
||||||
|
# Standard: https://llmstxt.org/
|
||||||
|
|
||||||
|
# Site Information
|
||||||
|
name: Juan Andrés Moreno Rubio - Professional CV
|
||||||
|
description: Interactive curriculum vitae of Juan Andrés Moreno Rubio, a Senior Technical Consultant and Full-Stack Developer with 20 years of experience in web development, SAP Customer Data Cloud, authentication systems, and AI-assisted development.
|
||||||
|
|
||||||
|
# Primary Content
|
||||||
|
This website presents the professional profile of Juan Andrés Moreno Rubio, including:
|
||||||
|
|
||||||
|
## Professional Summary
|
||||||
|
- Senior Technical Consultant specializing in SAP Customer Data Cloud (CDC)
|
||||||
|
- Full-Stack Developer with expertise in Go, Node.js, React, and HTMX
|
||||||
|
- 20 years of experience in high-availability systems
|
||||||
|
- Worked on Olympic Games platforms and airport authentication systems
|
||||||
|
- Advised 35-40 international clients on digital identity solutions
|
||||||
|
|
||||||
|
## Current Positions
|
||||||
|
- Senior SAP Technical Consultant at Olympic Broadcasting Services (2021-present)
|
||||||
|
- Senior SAP/CDC Technical Consultant at LIV Golf (2024-present)
|
||||||
|
|
||||||
|
## Key Expertise
|
||||||
|
- SAP Customer Data Cloud (CDC) implementation and consulting
|
||||||
|
- Authentication and identity management systems
|
||||||
|
- Full-stack web development (Go, Node.js, React, HTMX)
|
||||||
|
- AI-assisted development workflows
|
||||||
|
- GDPR compliance and data protection
|
||||||
|
|
||||||
|
## Notable Achievements
|
||||||
|
- Lead Technical Consultant for AENA Airports Authentication System (Spain)
|
||||||
|
- Implemented identity flows for millions of users across web and mobile
|
||||||
|
- Olympic Games broadcasting platform development
|
||||||
|
- 35-40 international client consultations
|
||||||
|
|
||||||
|
## Technical Skills
|
||||||
|
Programming Languages: Go, JavaScript, TypeScript, PHP, Java
|
||||||
|
Frontend: React, HTMX, HTML5, CSS3
|
||||||
|
Backend: Node.js, Go, Express, Hono
|
||||||
|
Databases: PostgreSQL, MySQL, SQLite, MongoDB
|
||||||
|
Cloud: AWS, Docker, CI/CD
|
||||||
|
Identity: SAP CDC, OAuth, OIDC, GDPR
|
||||||
|
|
||||||
|
## Education
|
||||||
|
- Computing Engineering, Bachelor's Degree - Universidad de Extremadura (1999-2009)
|
||||||
|
|
||||||
|
## Languages
|
||||||
|
- Spanish (Native)
|
||||||
|
- English (Professional)
|
||||||
|
- Portuguese (Intermediate)
|
||||||
|
|
||||||
|
## Contact
|
||||||
|
- Website: https://juan.andres.morenorub.io
|
||||||
|
- LinkedIn: https://www.linkedin.com/in/juan-andres-moreno-rubio
|
||||||
|
- GitHub: https://github.com/juanatsap
|
||||||
|
- Location: Arrecife, Las Palmas de Gran Canaria, Spain
|
||||||
|
|
||||||
|
# Available Formats
|
||||||
|
- Web (interactive): https://juan.andres.morenorub.io/?lang=en (English)
|
||||||
|
- Web (interactive): https://juan.andres.morenorub.io/?lang=es (Spanish)
|
||||||
|
- PDF Download: Available via website
|
||||||
|
|
||||||
|
# Site Technology
|
||||||
|
Built with Go, HTMX, Hyperscript, and modern CSS. Features include:
|
||||||
|
- Bilingual support (English/Spanish)
|
||||||
|
- Light/Dark/Auto theme modes
|
||||||
|
- Responsive design for all devices
|
||||||
|
- Accessible (WCAG AA compliant)
|
||||||
|
- Print-friendly version
|
||||||
|
|
||||||
|
# Preferred Citation
|
||||||
|
When referencing this CV, please cite as:
|
||||||
|
"Juan Andrés Moreno Rubio, Senior Technical Consultant - Professional CV, https://juan.andres.morenorub.io"
|
||||||
|
|
||||||
|
# Last Updated
|
||||||
|
2025-11-30
|
||||||
+86
-6
@@ -1,22 +1,29 @@
|
|||||||
# robots.txt for juan.andres.morenorub.io
|
# robots.txt for juan.andres.morenorub.io
|
||||||
|
# Last Updated: 2025-11-30
|
||||||
|
|
||||||
# Allow all search engines
|
# =============================================================================
|
||||||
|
# DEFAULT RULES - Allow all search engines
|
||||||
|
# =============================================================================
|
||||||
User-agent: *
|
User-agent: *
|
||||||
Allow: /
|
Allow: /
|
||||||
|
|
||||||
# Disallow admin/internal paths (if any in future)
|
# Disallow admin/internal paths
|
||||||
Disallow: /admin/
|
Disallow: /admin/
|
||||||
Disallow: /api/internal/
|
Disallow: /api/internal/
|
||||||
Disallow: /.git/
|
Disallow: /.git/
|
||||||
Disallow: /.env
|
Disallow: /.env
|
||||||
|
|
||||||
# Sitemap location
|
# =============================================================================
|
||||||
|
# SITEMAPS & AI CONTENT
|
||||||
|
# =============================================================================
|
||||||
Sitemap: https://juan.andres.morenorub.io/static/sitemap.xml
|
Sitemap: https://juan.andres.morenorub.io/static/sitemap.xml
|
||||||
|
|
||||||
# Crawl-delay (optional, helps prevent server overload)
|
# LLMs.txt for AI crawlers (standard: https://llmstxt.org/)
|
||||||
# Crawl-delay: 1
|
# Location: https://juan.andres.morenorub.io/static/llms.txt
|
||||||
|
|
||||||
# Allow specific search engines (explicit)
|
# =============================================================================
|
||||||
|
# TRADITIONAL SEARCH ENGINES
|
||||||
|
# =============================================================================
|
||||||
User-agent: Googlebot
|
User-agent: Googlebot
|
||||||
Allow: /
|
Allow: /
|
||||||
|
|
||||||
@@ -34,3 +41,76 @@ Allow: /
|
|||||||
|
|
||||||
User-agent: YandexBot
|
User-agent: YandexBot
|
||||||
Allow: /
|
Allow: /
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# AI CRAWLERS & LLM BOTS - Explicitly allowed
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# OpenAI - ChatGPT, GPT-4
|
||||||
|
User-agent: GPTBot
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
User-agent: ChatGPT-User
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
# Anthropic - Claude
|
||||||
|
User-agent: ClaudeBot
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
User-agent: Claude-Web
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
User-agent: anthropic-ai
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
# Google AI - Bard, Gemini
|
||||||
|
User-agent: Google-Extended
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
# Meta AI
|
||||||
|
User-agent: FacebookBot
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
User-agent: Meta-ExternalAgent
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
User-agent: meta-externalagent
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
# Perplexity AI
|
||||||
|
User-agent: PerplexityBot
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
# Cohere AI
|
||||||
|
User-agent: cohere-ai
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
# Common Crawl (used by many AI models)
|
||||||
|
User-agent: CCBot
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
# Amazon/Alexa
|
||||||
|
User-agent: Amazonbot
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
# Apple - Applebot (for Siri, Spotlight)
|
||||||
|
User-agent: Applebot
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
# Microsoft Copilot
|
||||||
|
User-agent: Copilot
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
# You.com AI
|
||||||
|
User-agent: YouBot
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
# Brave Search
|
||||||
|
User-agent: BraveBot
|
||||||
|
Allow: /
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# CRAWL RATE LIMITS (Optional)
|
||||||
|
# =============================================================================
|
||||||
|
# Uncomment if needed to prevent server overload
|
||||||
|
# Crawl-delay: 1
|
||||||
|
|||||||
+178
-8
@@ -124,19 +124,35 @@
|
|||||||
<link rel="dns-prefetch" href="https://fonts.googleapis.com">
|
<link rel="dns-prefetch" href="https://fonts.googleapis.com">
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Quicksand:wght@300;400;500;600;700&family=Source+Sans+Pro:wght@300;400;600&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Quicksand:wght@300;400;500;600;700&family=Source+Sans+Pro:wght@300;400;600&display=swap" rel="stylesheet">
|
||||||
|
|
||||||
<!-- Structured Data (JSON-LD) -->
|
<!-- Structured Data (JSON-LD) - Enhanced for AI-era SEO -->
|
||||||
|
<!-- Person Schema -->
|
||||||
<script type="application/ld+json">
|
<script type="application/ld+json">
|
||||||
{
|
{
|
||||||
"@context": "https://schema.org",
|
"@context": "https://schema.org",
|
||||||
"@type": "Person",
|
"@type": "Person",
|
||||||
|
"@id": "{{.CV.Personal.Website}}/#person",
|
||||||
"name": "{{.CV.Personal.Name}}",
|
"name": "{{.CV.Personal.Name}}",
|
||||||
|
"givenName": "{{.CV.Personal.FirstName}}",
|
||||||
|
"familyName": "{{.CV.Personal.LastName}}",
|
||||||
"jobTitle": "{{.CV.Personal.Title}}",
|
"jobTitle": "{{.CV.Personal.Title}}",
|
||||||
|
"description": "{{.CV.Summary}}",
|
||||||
"url": "{{.CV.Personal.Website}}",
|
"url": "{{.CV.Personal.Website}}",
|
||||||
|
"image": "{{.CV.Personal.Website}}/static/images/profile.jpg",
|
||||||
"email": "{{.CV.Personal.Email}}",
|
"email": "{{.CV.Personal.Email}}",
|
||||||
"telephone": "{{.CV.Personal.Phone}}",
|
"telephone": "{{.CV.Personal.Phone}}",
|
||||||
|
"birthDate": "{{.CV.Personal.DateOfBirth}}",
|
||||||
|
"birthPlace": {
|
||||||
|
"@type": "Place",
|
||||||
|
"name": "{{.CV.Personal.PlaceOfBirth}}"
|
||||||
|
},
|
||||||
|
"nationality": {
|
||||||
|
"@type": "Country",
|
||||||
|
"name": "{{.CV.Personal.Citizenship}}"
|
||||||
|
},
|
||||||
"address": {
|
"address": {
|
||||||
"@type": "PostalAddress",
|
"@type": "PostalAddress",
|
||||||
"addressLocality": "{{.CV.Personal.Location}}"
|
"addressLocality": "{{.CV.Personal.Location}}",
|
||||||
|
"addressCountry": "ES"
|
||||||
},
|
},
|
||||||
"sameAs": [
|
"sameAs": [
|
||||||
"{{.CV.Personal.LinkedIn}}",
|
"{{.CV.Personal.LinkedIn}}",
|
||||||
@@ -144,8 +160,13 @@
|
|||||||
"{{.CV.Personal.Domestika}}"
|
"{{.CV.Personal.Domestika}}"
|
||||||
],
|
],
|
||||||
"alumniOf": {
|
"alumniOf": {
|
||||||
"@type": "EducationalOrganization",
|
"@type": "CollegeOrUniversity",
|
||||||
"name": "Universidad de Extremadura"
|
"name": "Universidad de Extremadura",
|
||||||
|
"address": {
|
||||||
|
"@type": "PostalAddress",
|
||||||
|
"addressLocality": "Cáceres",
|
||||||
|
"addressCountry": "ES"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"knowsAbout": [
|
"knowsAbout": [
|
||||||
"Web Development",
|
"Web Development",
|
||||||
@@ -155,14 +176,163 @@
|
|||||||
"Go",
|
"Go",
|
||||||
"HTMX",
|
"HTMX",
|
||||||
"AI-Assisted Development",
|
"AI-Assisted Development",
|
||||||
"Full Stack Development"
|
"Full Stack Development",
|
||||||
|
"Authentication Systems",
|
||||||
|
"GDPR Compliance",
|
||||||
|
"Identity Management"
|
||||||
],
|
],
|
||||||
"worksFor": {
|
"knowsLanguage": [
|
||||||
"@type": "Organization",
|
{
|
||||||
"name": "Olympic Broadcasting Services"
|
"@type": "Language",
|
||||||
|
"name": "Spanish",
|
||||||
|
"alternateName": "es"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "Language",
|
||||||
|
"name": "English",
|
||||||
|
"alternateName": "en"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "Language",
|
||||||
|
"name": "Portuguese",
|
||||||
|
"alternateName": "pt"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"worksFor": [
|
||||||
|
{
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "Olympic Broadcasting Services",
|
||||||
|
"url": "https://www.obs.tv/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "LIV Golf",
|
||||||
|
"url": "https://www.livgolf.com/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"hasOccupation": [
|
||||||
|
{{- range $i, $exp := .CV.Experience}}{{if $i}},{{end}}
|
||||||
|
{
|
||||||
|
"@type": "Occupation",
|
||||||
|
"name": "{{$exp.Position}}",
|
||||||
|
"occupationLocation": {
|
||||||
|
"@type": "Place",
|
||||||
|
"name": "{{$exp.Location}}"
|
||||||
|
},
|
||||||
|
"description": "{{$exp.ShortDescription}}",
|
||||||
|
"skills": "{{range $j, $tech := $exp.Technologies}}{{if $j}}, {{end}}{{$tech}}{{end}}"
|
||||||
|
}
|
||||||
|
{{- end}}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- WebSite Schema -->
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "WebSite",
|
||||||
|
"@id": "{{.CV.Personal.Website}}/#website",
|
||||||
|
"name": "{{.CV.Personal.Name}} - Professional CV",
|
||||||
|
"url": "{{.CV.Personal.Website}}",
|
||||||
|
"description": "Interactive curriculum vitae of {{.CV.Personal.Name}}, {{.CV.Personal.Title}}",
|
||||||
|
"inLanguage": ["en", "es"],
|
||||||
|
"author": {
|
||||||
|
"@id": "{{.CV.Personal.Website}}/#person"
|
||||||
|
},
|
||||||
|
"potentialAction": {
|
||||||
|
"@type": "SearchAction",
|
||||||
|
"target": "{{.CV.Personal.Website}}/?lang={search_term_string}",
|
||||||
|
"query-input": "required name=search_term_string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<!-- BreadcrumbList Schema -->
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "BreadcrumbList",
|
||||||
|
"itemListElement": [
|
||||||
|
{
|
||||||
|
"@type": "ListItem",
|
||||||
|
"position": 1,
|
||||||
|
"name": "Home",
|
||||||
|
"item": "{{.CV.Personal.Website}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "ListItem",
|
||||||
|
"position": 2,
|
||||||
|
"name": "CV {{if eq .Lang "es"}}(Español){{else}}(English){{end}}",
|
||||||
|
"item": "{{.CV.Personal.Website}}/?lang={{.Lang}}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- ProfilePage Schema (for CV/Resume) -->
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "ProfilePage",
|
||||||
|
"mainEntity": {
|
||||||
|
"@id": "{{.CV.Personal.Website}}/#person"
|
||||||
|
},
|
||||||
|
"dateCreated": "2024-01-01",
|
||||||
|
"dateModified": "{{.CV.Meta.LastUpdated}}",
|
||||||
|
"name": "{{.CV.Personal.Name}} - Curriculum Vitae",
|
||||||
|
"description": "{{.CV.SEO.MetaDescription}}",
|
||||||
|
"inLanguage": "{{.Lang}}"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- EducationalOccupationalCredential Schema -->
|
||||||
|
{{range .CV.Education}}
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "EducationalOccupationalCredential",
|
||||||
|
"name": "{{.Degree}}",
|
||||||
|
"description": "{{.Field}}",
|
||||||
|
"educationalLevel": "Bachelor's Degree",
|
||||||
|
"credentialCategory": "degree",
|
||||||
|
"recognizedBy": {
|
||||||
|
"@type": "CollegeOrUniversity",
|
||||||
|
"name": "{{.Institution}}",
|
||||||
|
"address": {
|
||||||
|
"@type": "PostalAddress",
|
||||||
|
"addressLocality": "{{.Location}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dateCreated": "{{.EndDate}}"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
<!-- Course Schemas -->
|
||||||
|
{{range .CV.Courses}}
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "Course",
|
||||||
|
"name": "{{.Title}}",
|
||||||
|
"description": "{{if .ShortDescription}}{{.ShortDescription}}{{else}}{{.Description}}{{end}}",
|
||||||
|
"provider": {
|
||||||
|
"@type": "Organization",
|
||||||
|
"name": "{{.Institution}}"
|
||||||
|
},
|
||||||
|
"hasCourseInstance": {
|
||||||
|
"@type": "CourseInstance",
|
||||||
|
"courseMode": "onsite",
|
||||||
|
"location": {
|
||||||
|
"@type": "Place",
|
||||||
|
"name": "{{.Location}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"timeRequired": "{{.Duration}}"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{{end}}
|
||||||
</head>
|
</head>
|
||||||
<body {{if .ThemeClean}}class="theme-clean"{{end}}
|
<body {{if .ThemeClean}}class="theme-clean"{{end}}
|
||||||
_="on load call initScrollBehavior()
|
_="on load call initScrollBehavior()
|
||||||
|
|||||||
Reference in New Issue
Block a user