Media & Metadata: Images, Social Previews, and Tags
Enhance your learning content with rich media and effective metadata. This module covers adding images to your content, creating social share previews that look great when shared on Twitter/LinkedIn/Slack, and using tags strategically for discoverability.
Learning Objectives
- Add images to module content using Markdown syntax
- Create and configure social share images for rich previews
- Test social previews across multiple platforms
- Apply effective tagging strategies for content discovery
- Optimize metadata for SEO and user experience
- Troubleshoot common media and metadata issues
Prerequisites
- Completion of "Authoring Basics: Modules, Front Matter, and Sync" module
- Basic familiarity with image formats (JPEG, PNG, WebP)
- Access to HubSpot File Manager or external image hosting
- Understanding of Markdown syntax
- Optional: Design tool experience (Canva, Figma, or similar)
Scenario: Enriching Your Module with Media and Metadata
You've created a module about Kubernetes networking and want to make it more engaging and shareable. You'll add diagrams, create a social share image, optimize your tags, and verify everything renders correctly across platforms.
Structured Media Front Matter
The module front matter now supports a media
array that feeds the gallery on /learn/modules/<slug>
. Add an entry for every image or video you want rendered near the module introduction.
media:
- type: "image"
url: "https://hedgehog.cloud/hubfs/learn/k8s-service-types.png"
alt: "Diagram comparing Kubernetes service types"
caption: "Figure 1. Visual reference for Kubernetes service types."
credit: "Hedgehog Technical Marketing"
- type: "video"
url: "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
alt: "Screen recording that demonstrates configuring structured media"
caption: "Workflow walkthrough for adding media entries in module front matter."
thumbnail_url: "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.jpg"
Guardrails
- Alt text is mandatory—describe the key idea, not "image of..." redundantly.
- Use HTTPS URLs hosted on HubSpot or an approved CDN; avoid data URIs.
- Keep videos short (<2 minutes), provide a poster thumbnail, and rely on the built-in controls (no autoplay scripts).
- Omit the
media
field entirely when no assets are needed; empty arrays are ignored during sync.
Step 1: Understand Image Hosting Options
Before adding images, you need to host them somewhere accessible. You have two primary options:
Option 1: HubSpot File Manager (Recommended)
Navigate to HubSpot and upload your image:
# You'll do this in the HubSpot UI:
# 1. Marketing → Files and Templates → Files
# 2. Click "Upload" and select your image
# 3. Right-click uploaded image → "Copy public URL"
# 4. URL will be: https://hedgehog.cloud/hubfs/...
Option 2: External CDN
If using an external service like Cloudinary or AWS S3:
# Upload to your CDN and get public HTTPS URL
# Example URLs:
# https://res.cloudinary.com/your-account/image/upload/diagram.png
# https://your-bucket.s3.amazonaws.com/diagrams/network-flow.png
Requirements for all images:
- Publicly accessible (no authentication)
- HTTPS URL (not HTTP)
- Reasonable file size (< 2MB for content images)
- Appropriate format (JPEG, PNG, WebP, SVG)
Verify your image URL works:
# Test the URL is publicly accessible
curl -I https://hedgehog.cloud/hubfs/learn/kubernetes-networking-diagram.png
# Should return: HTTP/2 200
Step 2: Add Images to Module Content
Add images using standard Markdown syntax:
# Edit your module README.md
cat >> content/modules/kubernetes-networking/README.md << 'EOF'
### Understanding Service Types
Kubernetes offers several service types for different networking needs:

The diagram above shows:
- **ClusterIP**: Internal-only access
- **NodePort**: External access via node ports
- **LoadBalancer**: Cloud provider load balancer
- **ExternalName**: DNS alias to external service
EOF
Markdown image syntax:

Best practices:
- Alt text: Describe the image for screen readers and SEO
- Image size: Keep content images under 500KB (optimize/compress)
- Placement: Put images near related text
- Captions: Add explanatory text below images when helpful
Verify Markdown syntax:
# Check image syntax is correct
grep "^!\[" content/modules/kubernetes-networking/README.md
Step 3: Create a Social Share Image
Social share images appear when your content is shared on Twitter, LinkedIn, Facebook, or Slack. They should be eye-catching and branded.
Image specifications:
- Size: 1200 × 630 pixels (1.91:1 aspect ratio)
- Format: JPEG or WebP
- File size: < 300 KB
- Safe zone: Keep text/logos within center 1200 × 600 pixels
Design your image (using Canva, Figma, or similar):
# Create a new design in your tool:
# - Canvas size: 1200 × 630 pixels
# - Background: Brand colors or relevant imagery
# - Title: Module name (large, readable font 60-80pt)
# - Branding: Hedgehog logo in corner
# - Avoid clutter: Keep it simple and focused
Example design elements:
- Large title: "Kubernetes Networking"
- Subtitle: "Services, Ingress & Network Policies"
- Hedgehog logo (bottom right corner)
- Tech-themed background or abstract pattern
- High contrast for readability
Export settings:
- Format: JPEG
- Quality: 80-90%
- Resolution: 1200 × 630 pixels exactly
Step 4: Upload and Reference Social Image
Upload your social image to HubSpot:
# In HubSpot File Manager:
# 1. Upload your social image (e.g., k8s-networking-share.jpg)
# 2. Organize in /learn/ folder
# 3. Copy public URL
Add the social_image
field to your module front matter:
cat > content/modules/kubernetes-networking/README.md << 'EOF'
---
title: "Kubernetes Networking: Services, Ingress, and Network Policies"
slug: "kubernetes-networking"
difficulty: "intermediate"
estimated_minutes: 35
tags:
- kubernetes
- networking
- services
- ingress
description: "Master Kubernetes networking concepts including Services, Ingress controllers, and Network Policies for production deployments."
social_image: "https://hedgehog.cloud/hubfs/learn/k8s-networking-share.jpg"
---
EOF
Key points:
- Field name is
social_image
(notsocial_image_url
) - Use full HTTPS URL
- Image must be publicly accessible
- If omitted, system uses default branded image
Verify front matter syntax:
# Check social_image field
grep "^social_image:" content/modules/kubernetes-networking/README.md
Step 5: Sync Your Changes
Push your updated module with images and social metadata to HubDB:
# Run the sync
npm run sync:content
Expected output:
✓ Updated: Kubernetes Networking: Services, Ingress, and Network Policies
✅ Sync complete! Table published.
The sync script:
- Parses
social_image
from front matter - Converts Markdown to HTML (preserving
<img>
tags) - Stores social image URL in HubDB column
- Templates use it to generate Open Graph and Twitter Card meta tags
Step 6: Test Social Preview on Facebook
Use Facebook's debugger to verify your social image appears correctly:
# Open in browser:
echo "Visit: https://developers.facebook.com/tools/debug/"
# In the debugger:
# 1. Enter: https://hedgehog.cloud/learn/kubernetes-networking
# 2. Click "Debug"
# 3. Check the preview card shows your image
# 4. Verify title and description are correct
What to verify:
- ✅ Image loads and displays
- ✅ Image is 1200 × 630 pixels (shown in debugger)
- ✅ Title matches your module title
- ✅ Description matches your
description
field - ✅ No warnings about image size/format
Common issues:
- "Could not retrieve data": Image URL not accessible
- "Image too small": Use exactly 1200 × 630 pixels
- "Missing image": Check
social_image
field syntax
If you need to refresh the cache:
# Click "Scrape Again" in Facebook debugger
# This forces Facebook to fetch fresh data
Step 7: Test Social Preview on Twitter
Verify your Twitter Card renders correctly:
# Open in browser:
echo "Visit: https://cards-dev.twitter.com/validator"
# In the validator:
# 1. Enter: https://hedgehog.cloud/learn/kubernetes-networking
# 2. Click "Preview card"
# 3. Verify "summary_large_image" card displays
What to check:
- ✅ Large image card (not small summary)
- ✅ Image fills card width
- ✅ Title and description visible below image
- ✅ No image warnings
Twitter caches aggressively, so updates may take time to appear in real tweets.
Step 8: Test Social Preview on LinkedIn
LinkedIn has its own post inspector:
# Open in browser:
echo "Visit: https://www.linkedin.com/post-inspector/"
# In the inspector:
# 1. Enter: https://hedgehog.cloud/learn/kubernetes-networking
# 2. Click "Inspect"
# 3. Verify preview shows your social image
LinkedIn uses Open Graph tags like Facebook, so if Facebook preview works, LinkedIn should too.
Step 9: Test Slack Unfurling
Slack automatically "unfurls" links to show rich previews:
# In any Slack channel:
# 1. Paste: https://hedgehog.cloud/learn/kubernetes-networking
# 2. Press Enter
# 3. Verify rich preview appears with image
Slack preview includes:
- Social image (large)
- Module title
- Description
- Site name (Hedgehog Learn)
If preview doesn't appear:
- Check if Slack unfurling is enabled for the channel
- Verify image URL is accessible from Slack's servers
- Try removing and re-pasting the link
Step 10: Apply Effective Tagging Strategy
Tags help learners discover your content. Add relevant, specific tags:
---
tags:
- kubernetes
- networking
- services
- ingress
- network-policies
- cloud-native
---
Tagging best practices:
1. Use specific tags:
# ❌ Too generic
tags: [technology, cloud, tutorial]
# ✅ Specific and useful
tags: [kubernetes, networking, services, ingress]
2. Include technology versions (if applicable):
tags: [kubernetes-1.29, docker, containerd]
3. Add skill level indicators:
tags: [kubernetes, intermediate, networking, production]
4. Use consistent naming:
# ✅ Consistent hyphenation
tags: [kubernetes-networking, network-policies, service-mesh]
# ❌ Inconsistent
tags: [kubernetes_networking, network-policies, servicemesh]
5. Limit to 5-8 tags:
# Too many tags dilute effectiveness
# Focus on most relevant terms
View existing tags for consistency:
# See what tags are used across modules
grep -h "^ - " content/modules/*/README.md | sort | uniq -c | sort -rn | head -20
Step 11: Optimize Metadata for SEO
Your description
field is critical for SEO and social sharing. Optimize it:
# Check current description length
grep "^description:" content/modules/kubernetes-networking/README.md | wc -c
# Aim for 120-160 characters
Good description example:
description: "Master Kubernetes networking with hands-on labs covering Services, Ingress controllers, and Network Policies for production deployments."
# 140 characters - perfect length
Description best practices:
- Length: 120-160 characters (including field name)
- Action-oriented: Start with verbs (Learn, Master, Build, Deploy)
- Include key terms: Mention main topics/technologies
- Avoid jargon: Clear language for diverse audience
- No special characters: Avoid quotes, pipes, or unusual symbols
Bad description examples:
# ❌ Too short (not descriptive)
description: "Learn about Kubernetes networking."
# ❌ Too long (gets truncated)
description: "This comprehensive module will teach you everything you need to know about Kubernetes networking including Services, Ingress controllers, Network Policies, DNS, and advanced troubleshooting techniques."
# ❌ Not action-oriented
description: "A module about Kubernetes networking concepts."
Step 12: Add Image Compression
Large images slow page load. Compress before uploading:
# Using ImageMagick (if installed)
convert input.png -quality 85 -resize 800x output.jpg
# Using cwebp for WebP format
cwebp -q 80 input.png -o output.webp
# Online tools alternative:
# - TinyPNG.com
# - Squoosh.app
# - Compressor.io
Target sizes:
- Content images: < 500 KB
- Social images: < 300 KB
- Icons/logos: < 50 KB
Check image file size:
ls -lh static/images/kubernetes-networking-diagram.png
# Should show reasonable size like 245K, not 2.1M
Step 13: Verify All Metadata
Check your complete front matter includes all recommended fields:
cat content/modules/kubernetes-networking/README.md | head -15
Complete metadata example:
---
title: "Kubernetes Networking: Services, Ingress, and Network Policies"
slug: "kubernetes-networking"
difficulty: "intermediate"
estimated_minutes: 35
version: "v1.29"
validated_on: "2025-10-14"
tags:
- kubernetes
- networking
- services
- ingress
- network-policies
description: "Master Kubernetes networking with hands-on labs covering Services, Ingress controllers, and Network Policies for production deployments."
social_image: "https://hedgehog.cloud/hubfs/learn/k8s-networking-share.jpg"
order: 200
---
Metadata checklist:
- ✅
title
- Clear, descriptive - ✅
slug
- Matches directory name - ✅
difficulty
- Accurate assessment - ✅
estimated_minutes
- Realistic time - ✅
tags
- 5-8 relevant, specific tags - ✅
description
- 120-160 chars, action-oriented - ✅
social_image
- 1200×630, < 300KB, HTTPS URL - ✅
version
- Tool/product version (if applicable) - ✅
validated_on
- Current date
Step 14: Verify Live Page Rendering
Visit your module page and verify everything renders correctly:
echo "Live URL: https://hedgehog.cloud/learn/kubernetes-networking"
echo "Debug URL: https://hedgehog.cloud/learn/kubernetes-networking?debug=1"
Visual verification:
- ✅ Content images load and display properly
- ✅ Images have appropriate size and quality
- ✅ Alt text is meaningful (check browser inspector)
- ✅ Page loads quickly (< 3 seconds)
Debug verification:
- ✅
has full_content? true
- ✅
social_image
field populated in debug output - ✅ Tags display correctly
- ✅ Metadata fields match front matter
Browser inspector verification (View → Developer → Inspect Element):
<!-- Check for meta tags in <head> -->
<meta property="og:image" content="https://hedgehog.cloud/hubfs/learn/k8s-networking-share.jpg">
<meta name="twitter:image" content="https://hedgehog.cloud/hubfs/learn/k8s-networking-share.jpg">
<meta name="twitter:card" content="summary_large_image">
If social image meta tags are missing, the template may need updating.
Concepts & Deep Dive
Social Sharing Meta Tags
When you add a social_image
to your front matter, the template generates Open Graph and Twitter Card meta tags:
Open Graph (Facebook, LinkedIn):
<meta property="og:image" content="https://hedgehog.cloud/hubfs/learn/your-image.jpg">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:title" content="Your Module Title">
<meta property="og:description" content="Your description...">
<meta property="og:type" content="article">
<meta property="og:url" content="https://hedgehog.cloud/learn/your-slug">
Twitter Cards:
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://hedgehog.cloud/hubfs/learn/your-image.jpg">
<meta name="twitter:title" content="Your Module Title">
<meta name="twitter:description" content="Your description...">
Fallback Behavior
If no social_image
is provided, the system falls back to a default:
# No social_image in front matter
---
title: "My Module"
description: "..."
---
Templates use the default configured in constants.json
:
{
"DEFAULT_SOCIAL_IMAGE_URL": "https://hedgehog.cloud/hubfs/social-share-default.png"
}
This ensures every page has a social preview, even without custom images.
Image Formats Compared
JPEG:
- Best for: Photos, complex images
- Pros: Small file size, universal support
- Cons: No transparency, lossy compression
PNG:
- Best for: Diagrams, screenshots, images with text
- Pros: Lossless, supports transparency
- Cons: Larger file size
WebP:
- Best for: Modern web use, all image types
- Pros: Better compression than JPEG/PNG, supports transparency
- Cons: Older browsers don't support (rare now)
SVG:
- Best for: Icons, logos, simple diagrams
- Pros: Scalable, tiny file size
- Cons: Not suitable for complex images
Recommendation: Use WebP for social images (best quality/size ratio) and JPEG/PNG for content images based on type.
Tag Taxonomy Strategy
Effective tagging follows a hierarchy:
Level 1: Technology/Platform
tags: [kubernetes, docker, aws, azure, terraform]
Level 2: Specific Feature/Topic
tags: [kubernetes-networking, docker-compose, aws-eks, terraform-modules]
Level 3: Use Case/Pattern
tags: [service-mesh, container-orchestration, infrastructure-as-code]
Level 4: Skill/Audience
tags: [beginner, intermediate, advanced, production-ready]
Combine 1-2 tags from each level for effective discovery.
SEO Best Practices
Your metadata directly impacts SEO:
1. Title Tag (from title
field):
- Primary ranking signal
- Keep under 60 characters for display
- Include main keyword near beginning
2. Meta Description (from description
field):
- Doesn't affect ranking but improves click-through
- 120-160 characters optimal
- Include call-to-action
3. Image Alt Text:
- Helps image search ranking
- Accessibility requirement
- Describe content, not just keywords
4. Tags (from tags
field):
- Not direct ranking signal but helps categorization
- Use consistent terms across related content
- Align with user search terms
Platform-Specific Preview Sizes
Different platforms crop/display images differently:
Facebook/LinkedIn:
- Displays: 1200 × 630 (full frame)
- Safe zone: Center 1200 × 600
- Mobile: May crop to 1.91:1 ratio
Twitter:
- Displays: 1200 × 628 (summary_large_image)
- Ratio: 2:1
- Falls back to smaller card if image missing
Slack:
- Displays: Variable (responsive)
- Prefers: 1200 × 630
- Shows description below image
Design tip: Keep critical content (text, logos) in the center 1100 × 580 pixel zone to avoid cropping on any platform.
Troubleshooting
Social Image Not Appearing
Symptom: Preview shows default image instead of custom image
Cause: URL not accessible, HTTPS issue, or cache
Fix:
# 1. Test URL directly
curl -I https://hedgehog.cloud/hubfs/learn/your-image.jpg
# Should return 200, not 403 or 404
# 2. Check front matter syntax
grep "^social_image:" content/modules/your-module/README.md
# Should be: social_image: "https://..."
# 3. Re-sync
npm run sync:content
# 4. Clear platform cache
# Use Facebook debugger "Scrape Again" button
Content Images Not Loading
Symptom: Broken image icon (alt text visible but no image)
Cause: Incorrect URL, missing image, or permission issue
Fix:
# Verify image URL in Markdown
grep "!\[" content/modules/your-module/README.md
# Test each URL
curl -I https://hedgehog.cloud/hubfs/learn/diagram.png
# Should return 200
# Common issues:
# - Wrong path (check spelling)
# - HTTP instead of HTTPS
# - Private file (check HubSpot permissions)
Social Image Too Large
Symptom: Facebook debugger warns "Image too large"
Cause: File size exceeds platform limits
Fix:
# Check file size
curl -I https://hedgehog.cloud/hubfs/learn/your-image.jpg | grep -i content-length
# Calculate: bytes / 1024 / 1024 for MB
# Compress image
# Use online tools or ImageMagick:
convert input.jpg -quality 80 -resize 1200x630 output.jpg
# Re-upload to HubSpot and update URL
Target: < 300 KB for social images
Blurry or Pixelated Social Image
Symptom: Image looks blurry when shared
Cause: Wrong dimensions or upscaling
Fix:
# Check actual image dimensions
# Download and check:
curl -o temp.jpg https://hedgehog.cloud/hubfs/learn/your-image.jpg
file temp.jpg
# Should show: 1200 x 630
# If wrong dimensions:
# - Redesign at exactly 1200 × 630 pixels
# - Don't upscale smaller images
# - Export at high quality (80-90% JPEG quality)
Inconsistent Tags Across Modules
Symptom: Similar modules use different tag names
Cause: Lack of standardization
Fix:
# Audit existing tags
grep -h "^ - " content/modules/*/README.md | sort | uniq
# Create tag standards document or list
# Standardize variations:
# kubernetes / k8s → kubernetes
# docker-container / containers → containers
# net-policy / network-policy → network-policies
# Update modules to use consistent tags
# Re-sync
npm run sync:content
Description Too Long
Symptom: Description truncates on social cards
Cause: Exceeds 160 character limit
Fix:
# Check length
grep "^description:" content/modules/your-module/README.md | wc -c
# Rewrite to be concise
# Before (too long):
description: "This comprehensive module will teach you everything you need to know about Kubernetes networking including Services, Ingress controllers, Network Policies, and advanced troubleshooting."
# After (just right):
description: "Master Kubernetes networking with hands-on labs covering Services, Ingress controllers, and Network Policies for production."
Alt Text Missing
Symptom: Screen readers can't describe images, SEO impact
Cause: Empty alt text in Markdown
Fix:
# Find images without alt text
grep "!\[\]" content/modules/your-module/README.md
# Add descriptive alt text
# Before:

# After:

Alt text guidelines:
- Describe what the image shows
- Keep under 125 characters
- Don't start with "Image of..." or "Picture of..."
- Include relevant keywords naturally
Resources
- Social Images Documentation - Complete social image guide
- Course Authoring Guide - Content authoring reference
- Open Graph Protocol - Official OG tag specification
- Twitter Card Documentation - Twitter card types and validation
- Facebook Sharing Debugger - Test and refresh Open Graph previews
- TinyPNG - Online image compression
- Canva - Easy social image design tool
- Squoosh - Advanced image compression tool
- HubSpot File Manager Guide - Using HubSpot for media hosting