Skip to content

Latest commit

 

History

History
194 lines (149 loc) · 16.8 KB

seo-audit-2026-06.md

File metadata and controls

194 lines (149 loc) · 16.8 KB

SEO Audit — example42.com

Date: June 2026 | Scope: Full Site Audit | Auditor: Claude (Cowork)


Executive Summary

example42.com has a genuine and rare competitive moat — Alessandro Franceschi is credibly positioned as the world's longest-active Puppet consultant (since 2007) and that claim is front and center. The site also benefits from 174 blog posts, 22 podcast episodes, and solid technical foundations (HTTPS, Google Search Console verified, Open Graph tags, responsive layout). However, three problems are holding the site back significantly: 161 of 174 blog posts have no custom meta description (falling back to the generic site description), no canonical tags exist anywhere on the site, and the sitemap.xml is unrendered Jekyll template (Liquid variables ship raw to users). Fixing these three issues alone will produce meaningful ranking improvements. A fourth structural opportunity — creating dedicated landing pages for individual services and leveraging the Pabawi product launch — could meaningfully expand organic reach into adjacent keywords.

Top 3 priorities: (1) Add meta descriptions site-wide, especially to blog posts; (2) Fix the broken sitemap; (3) Create dedicated service landing pages with proper H1/H2 targeting.


Keyword Opportunity Table

Keyword Difficulty Opportunity Current Signal Intent Recommended Content
puppet consulting Low-Medium High Homepage ranks Commercial Homepage + dedicated /services/ page
puppet consultant Low High Homepage ranks Commercial Homepage, About/5Ws page
puppet support Low High Services page Commercial Dedicated landing page
puppet training Low-Medium High Services page Commercial Dedicated landing page
puppet health check Very Low High Services page (H2) Commercial Dedicated landing page
puppet infrastructure kickstart Very Low High Services page (H2) Commercial Dedicated landing page
puppet enterprise consulting Low High Implicit only Commercial New service page
ansible to puppet migration Very Low High Services page (H2) Commercial Dedicated landing page
puppet to ansible migration Very Low High Services page (H2) Commercial Same as above
psick puppet control repo Very Low Medium Blog + GitHub Informational Blog post / GitHub README
puppet hiera tutorial Low Medium Blog post (2021) Informational Refresh/update existing post
puppet module development Low Medium Implicit Commercial Blog + services page
devops podcast infrastructure Medium Medium ADI podcast Informational ADI landing page SEO
abnormal devops iterations podcast Very Low Medium ADI section Navigational ADI index page
puppet open source alternative Medium Medium Not covered Informational New blog post
configuration management consulting Medium Medium Weak Commercial Services page expansion
pabawi web frontend puppet Very Low High Blog posts (2026) Informational/Commercial Pabawi dedicated page
pabawi puppet proxmox Very Low High Blog posts Informational Pabawi blog series
tp desktop puppet Very Low Low One blog post Informational Expand existing
puppet error unknown resource type Very Low Medium 2022 post Informational Update/expand
puppet eyaml gpg hiera Very Low Medium 2020 post Informational Update for current Puppet versions

On-Page Issues

Page Issue Severity Fix
All 161 blog posts without description: field No custom meta description — falls back to generic site description for every post Critical Add description: frontmatter to each post. Quick win for recent posts; batch-update older ones.
All 22 ADI episodes head.html checks page.description only — episodes use summary: field, so all episode pages also fall back to generic site description Critical Add {% elsif page.summary %}{{ page.summary }}{% endif %} fallback in head.html for episodes
Entire site No <link rel="canonical"> tag anywhere High Add <link rel="canonical" href="{{ page.url | prepend: site.url }}"> to _includes/head.html
sitemap.xml Liquid template variables ({{ site.url }}, {% for post %}) are not being processed — raw template is served to crawlers High Move sitemap generation to a Jekyll plugin or use the jekyll-sitemap gem; verify rendered output at /sitemap.xml
Homepage H1 H1 is "Puppet | DevOps Professional Consulting" — vague, splits keyword with pipe, misses "consultant" and "Alessandro Franceschi" High Rewrite to something like: "Puppet & DevOps Consulting — Alessandro Franceschi, Puppet Expert Since 2007"
Services page Single long page covering 6+ services — all services share one <title> and one H1; individual services have no dedicated URL High Create /services/puppet-health-check/, /services/puppet-training/ etc. with dedicated titles and H1s
ADI episode pages H1 in adi_detail.html has mismatched open/close tags: <h1>…</h2> Medium Fix HTML: change closing </h2> to </h1> on line with guest/title
Blog posts H1 rendered inside blog_detail.html from {{ page.title }} — good. But many posts have # Title markdown H1 in body too, creating two H1s Medium Audit recent posts; remove leading # Title from post body markdown where layout already renders H1
robots.txt Disallows /img/ — prevents Google from crawling episode cover images and logo images used in OG tags Medium Remove Disallow: /img/ — image crawling helps Google Images and OG previews; only block truly private paths
All pages No structured data / JSON-LD schema markup Medium Add Organization schema to homepage; Person for Alessandro; Service for services page; PodcastEpisode for ADI episodes
wwwww/ page URL is /wwwww/ — confusing, not guessable, and provides no keyword signal Low Consider redirecting to /about/ with a cleaner slug and title
Blog index No meta description on /blog/ index Low Add description to blog/index.html frontmatter
Open Graph images All pages fall back to /img/pic-logo.png unless page.image is set — blog posts have no per-post image Low Add image: to blog post frontmatter for important/recent posts

Content Gap Analysis

1. No dedicated landing pages per service

Why it matters: All six services live as anchor-linked sections on one /services/ page. Google cannot rank /services/#puppet-health-check separately from the main page. Competitors like SPK and Open Infrastructure Services have individual pages per service that can rank for long-tail commercial queries. Recommended format: Dedicated pages at /services/puppet-health-check/, /services/puppet-training/, /services/ansible-puppet-migration/, etc. Priority: High | Effort: Moderate (half a day per page)

2. Pabawi has no dedicated product/SEO page

Why it matters: The site has 5 Pabawi blog posts in 2026 but no standalone /pabawi/ page with a clear value proposition. pabawi.example42.com exists as a subdomain but is a separate site that doesn't build example42.com's domain authority. Pabawi users searching "pabawi puppet" or "pabawi web frontend" will land on blog posts, not a conversion-optimized page. Recommended format: New /pabawi/ landing page with feature overview, screenshots, and links to GitHub + docs. Priority: High | Effort: Moderate

3. No "Puppet vs. Ansible" comparison content

Why it matters: "Ansible vs Puppet" is a high-volume commercial-intent query. Competitors (Red Hat, Spacelift, SPK) rank for this. example42 offers Ansible↔Puppet migration services and has the expertise to write definitively on this topic, but no content targets it. Recommended format: Long-form comparison blog post or guide Priority: High | Effort: Moderate (half day)

4. No Puppet 8 / modern Puppet content

Why it matters: The most recent technical Puppet posts are from 2020-2022. Queries like "puppet 8 upgrade", "puppet 7 to 8 migration", "puppet open source 2025" are uncontested and highly relevant to the services offered. Recommended format: Blog post series on Puppet 7→8 upgrade path Priority: High | Effort: Moderate

5. No "what is Puppet" / awareness-level content

Why it matters: The entire site targets decision-ready buyers. There's no content for the awareness funnel ("what is puppet", "why use puppet", "puppet vs chef"). These informational posts build authority and generate inbound links. Recommended format: Pillar page "What is Puppet and why it still matters in 2026" Priority: Medium | Effort: Moderate

6. Podcast SEO is underdeveloped

Why it matters: The ADI podcast index page at /AbnormalDevOpsIterations/ has no meta description, no structured PodcastSeries schema, and episode pages are not using the summary: field for meta descriptions. Each episode with a notable guest (Michael Stahnke, Dennis Kliban, etc.) is a missed opportunity to rank for "[guest name] devops podcast". Recommended format: Improve episode pages + add podcast schema Priority: Medium | Effort: Quick wins (1-2 hours for schema; 1 hour for template fix)

7. No case studies or client results

Why it matters: Competitors like SPK prominently feature client testimonials and case studies. example42 references "world-class expertise" but has no concrete customer proof content, which both supports SEO (unique content, E-E-A-T signals) and conversion. Recommended format: Even 2-3 anonymized case study blog posts Priority: Medium | Effort: Substantial


Technical SEO Checklist

Check Status Details
HTTPS ✅ Pass Site served over HTTPS; GitHub Pages handles SSL
Mobile responsive ✅ Pass Bootstrap-based layout, viewport meta tag present
Google Search Console ✅ Pass Verification meta tag present
Open Graph / Twitter Cards ✅ Pass Tags in head.html; falls back to site-level defaults
Favicons ✅ Pass Full set of favicon sizes present
robots.txt ⚠️ Warning Disallows /img/ unnecessarily; blocks image crawling
Sitemap ❌ Fail Template variables not rendered; raw Liquid served to crawlers
Canonical tags ❌ Fail No <link rel="canonical"> anywhere on the site
Meta descriptions ❌ Fail Only 13/174 posts and 0/22 episodes have custom descriptions
Structured data (JSON-LD) ❌ Fail No schema markup anywhere
H1 uniqueness ⚠️ Warning ADI episode template has mismatched H1/H2 close tag
Internal linking ⚠️ Warning Blog posts rarely link to the services page; homepage links to services but not to individual episodes
Page speed ⚠️ Warning Bootstrap CSS + Font Awesome loaded synchronously; Google Fonts loaded with ?family= (render-blocking) — no preconnect hints
Image alt text ✅ Pass Layout templates include alt text on images; episode images use descriptive alt
URL structure ✅ Pass Clean pretty URLs (/blog/YYYY/MM/DD/title/, /AbnormalDevOpsIterations/NNN/)
XML feed ✅ Pass atom.xml present and covers all posts
Redirect behavior ✅ Pass example42.com/services → /services/ redirect works correctly
Google Fonts ⚠️ Warning Loaded via blocking <link> without display=swap; add &display=swap to the font URL

Competitor Comparison

Dimension example42.com SPK and Associates (spkaa.com) Open Infrastructure Services (openinfrastructure.co)
Puppet-specific focus ✅ Pure Puppet/DevOps ❌ Puppet is one of 20+ tools ✅ Puppet + GCP
Service pages (dedicated URLs) ❌ All on one page ✅ Per-service pages ✅ Per-service sub-pages
Content volume ✅ 174 posts (though many old) ✅ High volume, recent ⚠️ Lower volume
Structured data ❌ None ✅ Article schema on posts ✅ Basic meta
Canonical tags ❌ None ✅ Present ✅ Present
Client social proof ❌ None visible ✅ Named testimonials, case studies ⚠️ Credentials cited (Pro Puppet co-author)
Podcast / multimedia ✅ ADI podcast (unique asset) ❌ None ❌ None
Open source portfolio ✅ Strong (PSICK, Tiny Puppet, Pabawi) ❌ None ⚠️ Some GitHub activity
Personal brand / E-E-A-T ✅ Strongest ("since 2007") ❌ Company brand ✅ Strong (ex-Puppet Inc. founders)
Publishing recency ✅ Active in 2026 ✅ Active weekly ⚠️ Sporadic
Winner Personal brand, OSS, podcast Technical SEO, content ops Niche depth

Prioritized Action Plan

Quick Wins — do this week

  1. Fix the episode meta description fallback — In _includes/head.html, change the description meta to fall back to page.summary for episodes. One-line template change; covers all 22 episodes immediately.

    • Impact: High | Effort: 30 minutes
  2. Add canonical tag to head.html — Add <link rel="canonical" href="{{ page.url | prepend: site.url }}"> to _includes/head.html. Prevents any duplicate content issues with category/tag pages.

    • Impact: High | Effort: 15 minutes
  3. Fix robots.txt — Remove Disallow: /img/. Images are public assets that help with Google Images discovery and OG preview rendering.

    • Impact: Medium | Effort: 5 minutes
  4. Fix sitemap.xml — Install jekyll-sitemap gem (add to Gemfile and _config.yml), delete the broken manual sitemap.xml. GitHub Pages supports this gem natively.

    • Impact: High | Effort: 30 minutes
  5. Fix ADI episode H1 tag — In _includes/adi_detail.html, fix </h2> → </h1> on the guest/title line.

    • Impact: Medium | Effort: 5 minutes
  6. Add descriptions to the 8 most recent blog posts — The 2024-2026 posts (Pabawi series, Swamp posts) are the most likely to receive traffic. Add description: frontmatter now.

    • Impact: Medium | Effort: 1 hour
  7. Add &display=swap to Google Fonts URL — In _includes/head.html, change the Lato font URL to include &display=swap to prevent render-blocking.

    • Impact: Low-Medium | Effort: 5 minutes

Strategic Investments — this quarter

  1. Create dedicated service landing pages — Break the monolithic /services/ page into individual pages: /services/puppet-health-check/, /services/puppet-training/, /services/ansible-migration/, etc. Each gets its own <title>, H1, meta description, and internal links. This is the single highest-leverage SEO move for commercial keyword ranking.

    • Impact: High | Effort: 1 day | Dependency: Redesign navigation
  2. Create /pabawi/ landing page — A dedicated page for Pabawi on example42.com to capture product-level searches and convert Pabawi users into consulting clients. Link from the homepage Open Source section and from the blog posts.

    • Impact: High | Effort: Half day
  3. Write "Ansible vs Puppet" comparison post — Target the "ansible vs puppet" and "puppet to ansible migration" queries directly. Cite real experience; link to the migration service page.

    • Impact: High | Effort: Half day
  4. Write Puppet 8 upgrade guide — "Puppet 7 to 8 migration guide" is low competition, high relevance to customers. Example42's active Puppet expertise makes this authoritative.

    • Impact: High | Effort: Half day to 1 day
  5. Add JSON-LD schema markup — Add Organization + Person schema to homepage, Service schema to each service page, PodcastSeries to the ADI index, PodcastEpisode to each episode. This supports Google's Knowledge Panel, rich results, and E-E-A-T signals.

    • Impact: Medium | Effort: Half day
  6. Batch-add meta descriptions to blog posts — The bin/get_quotes.py script already uses OpenAI to generate summaries from transcripts. A similar script targeting blog post content could batch-generate description: frontmatter for the ~161 posts missing it. Alternatively, manually write descriptions for the top 30 most-visited posts.

    • Impact: High | Effort: 1-2 days (script approach)
  7. Build internal linking structure — Add "You might also like" or contextual links within blog posts pointing to related service pages. Particularly: any post mentioning Puppet health, migrations, or training should link to the relevant service section.

    • Impact: Medium | Effort: Ongoing (1-2 hours per batch of posts)

Want me to draft content briefs for the service landing pages, write a Puppet 8 upgrade post, or generate meta descriptions for a batch of blog posts?