A modern Jekyll-based travel blog documenting adventures around the world. δΈθΎΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΡΠ΅ΠΌ δΈθΎΉ ΠΏΡΡΠ΅ΡΠ΅ΡΡΠ²ΡΠ΅ΠΌ - Programming while traveling.
- Modern Jekyll Architecture - Optimized for performance and maintainability
- Multi-language Content - Support for Russian, Chinese, and English posts
- Responsive Design - Optimized for all devices and screen sizes
- SEO Optimized - Comprehensive meta tags, structured data, and social media integration
- Fast Loading - Compressed assets, optimized images, and efficient caching
- Travel-focused - Custom layouts for travel posts with image galleries and optional HLS video (see
CLAUDE.md) - Taxonomy System - Organized by categories and tags with archive pages
- Security Enhanced - Modern security headers and HTTPS enforcement
- Ruby 3.0+
- Bundler gem
- Jekyll 4.3+
-
Clone the repository
git clone https://github.com/catdog905/blog.git cd blog -
Set up Ruby gem environment
export GEM_HOME=$HOME/.gem
-
Install dependencies
bundle install
-
Start local development server
bundle exec jekyll serve -
Visit your site
http://localhost:4000
bundle exec jekyll buildBuilt site will be in the _site directory.
blog/
βββ _sass/ # Modular Sass architecture
β βββ _variables.scss # Design system variables
β βββ _mixins.scss # Reusable mixins
β βββ _base.scss # Base HTML styles
β βββ _posts.scss # Post-specific styles
β βββ _travel-home.scss # Home page styles
β βββ _images.scss # Image galleries & handling
β βββ _archive.scss # Category/tag archive pages
β βββ _layouts.scss # Layout-specific styles
βββ _data/ # Structured site data
β βββ navigation.yml # Site navigation structure
β βββ site.yml # Site metadata and settings
βββ _includes/ # Reusable template parts
β βββ head.html # Enhanced SEO head section
β βββ youtube.html # YouTube embed helper
βββ _layouts/ # Page templates
β βββ base.html # Base template with compression
β βββ post.html # Travel post layout
β βββ travel-home.html # Home page layout
β βββ page.html # Static page layout
β βββ default.html # Default layout
βββ _posts/travel/ # Travel blog posts
β βββ beijing/
β βββ chengdu/
β βββ zhangjiajie/
β βββ ... # Organized by destination
βββ categories/ # Category archive pages
βββ tags/ # Tag archive pages
βββ css/
β βββ main.scss # Single CSS entry point
βββ utils/
β βββ list-post-media.sh # List media paths referenced by a post
β βββ process-post-images.sh # WebP derivatives + LQIP + manifest.json
β βββ process-post-videos.sh # Adaptive HLS into derived/ (no upscale)
β βββ download_photos.sh # Image management utility
βββ _config.yml # Jekyll configuration
βββ Gemfile # Ruby dependencies
βββ CLAUDE.md # AI assistant instructions
βββ OPTIMIZATION.md # Technical documentation
βββ README.md # This file
-
Create post file
# Format: YYYY-MM-DD-destination.md _posts/travel/paris/2024-03-15-paris.md -
Add frontmatter
--- layout: post title: "Paris Adventure" preview: "https://storage.yandexcloud.net/path/to/preview.jpg" description: "Exploring the City of Light" categories: [travel, europe] tags: [paris, france, museums, food, architecture] location: city: "Paris" country: "France" coordinates: [48.8566, 2.3522] lang: en ---
-
Write content with images
Your travel story here... ![Image description][image-ref] ## Horizontal Gallery <div class="horizontal-scroll"> ![Gallery image 1][img1] ![Gallery image 2][img2] ![Gallery image 3][img3] </div> [image-ref]: /path/to/image.jpg [img1]: /path/to/gallery1.jpg [img2]: /path/to/gallery2.jpg [img3]: /path/to/gallery3.jpg
- External hosting via Yandex Cloud for performance
- Local fallbacks supported in
2025/01/12/imgs/structure - Automatic optimization via JavaScript for responsive display
- Lazy loading enabled for better performance
- Horizontal galleries with smooth scrolling
- Russian (ru) - Primary language for travel content
- Chinese (zh) - For China-focused posts
- English (en) - International audience
All colors, fonts, and spacing are controlled via Sass variables in _sass/_variables.scss:
// Colors
$primary-color: #1A1919;
$background-color: #FFFFFF;
$text-color: #1A1919;
// Typography
$font-family-base: 'Inter', 'Helvetica Neue', 'Helvetica', sans-serif;
$font-size-base: 10px;
$font-size-content: 1.7rem;
// Spacing
$spacing-base: 20px;
$max-content-width: 700px;
// Breakpoints
$mobile-breakpoint: 680px;The modular Sass architecture makes it easy to:
- Add new color schemes
- Implement dark mode
- Create new layout components
- Extend responsive behavior
Key configuration options:
# Basic settings
title: "XiongXiaomao blog"
description: "Travel blog documenting adventures around the world"
url: "https://2xiaomao.ru"
# SEO and social
author:
name: "Yaroslav Kivaev"
github: "yarkivaev"
# Content
paginate: 5
show_excerpts: true
# Performance
sass:
style: compressed
compress_html:
clippings: allCustomize site navigation and destination listings:
main:
- title: "Home"
url: /
- title: "Categories"
url: /categories/
- title: "Tags"
url: /tags/
destinations:
- name: "Beijing"
slug: "beijing"
country: "China"
featured: true- Sass compilation with compression
- HTML minification removes whitespace
- Image optimization with lazy loading
- Font preloading for faster text rendering
- Single CSS file reduces HTTP requests
- Gzip compression ready for production
- Content Security Policy prevents XSS attacks
- Security headers protect against common vulnerabilities
- HTTPS enforcement ensures secure connections
- Input sanitization via Jekyll's built-in protections
- Automatic meta tags via jekyll-seo-tag
- XML sitemap generation
- RSS feed for content syndication
- Structured data for rich search results
- Social media optimization (Open Graph, Twitter Cards)
- Canonical URLs prevent duplicate content issues
- Google Analytics - Ready for tracking ID
- GitHub Integration - Automatic metadata
- Social Sharing - Optimized for all major platforms
- Mobile-first approach with progressive enhancement
- Flexible grid system for different screen sizes
- Touch-optimized interactions for mobile devices
- Fast loading on slow connections
# Start with live reload
bundle exec jekyll serve --livereload
# Build for production
bundle exec jekyll build
# Check for issues
bundle exec jekyll doctorRequires GNU bash 5 and ImageMagick (brew install bash imagemagick). Scripts use /opt/homebrew/bin/bash.
export PATH="/opt/homebrew/bin:$PATH"
# Download images from Yandex Cloud
./utils/download_photos.sh
# List all local media for a travel post (images + expanded HLS trees)
./utils/list-post-media.sh --check _posts/travel/italy/2026-04-10-italy.md
# Generate WebP 1400/2400 + LQIP blur placeholders β travel/<slug>/derived/ (gitignored)
./utils/list-post-media.sh _posts/travel/italy/2026-04-10-italy.md \
| ./utils/process-post-images.sh --post _posts/travel/italy/2026-04-10-italy.md
# Only a subdir or single file (relative to travel/<slug>/)
./utils/list-post-media.sh --prefix rome/from_kate _posts/travel/italy/2026-04-10-italy.md \
| ./utils/process-post-images.sh --post _posts/travel/italy/2026-04-10-italy.md
./utils/list-post-media.sh --prefix rome/from_kate/19.jpg _posts/travel/italy/2026-04-10-italy.md \
| ./utils/process-post-images.sh --post _posts/travel/italy/2026-04-10-italy.md
./utils/list-post-media.sh _posts/travel/italy/2026-04-10-italy.md \
| ./utils/process-post-videos.sh --post _posts/travel/italy/2026-04-10-italy.md
bundle exec jekyll build
# Upload travel/<slug>/ (originals + derived/) to Yandex Object Storage (AWS CLI + credentials)
aws s3 sync travel/italy/ s3://yarkivaev-blog/italy/ \
--endpoint-url=https://storage.yandexcloud.net \
--exclude ".DS_Store"CORS (required for HLS via hls.js from localhost:4000 or 2xiaomao.ru): apply config/yandex-bucket-cors.json on bucket yarkivaev-blog in the Yandex Cloud console (bucket β Security β CORS), or via aws s3api put-bucket-cors --bucket yarkivaev-blog --cors-configuration file://config/yandex-bucket-cors.json --endpoint-url=https://storage.yandexcloud.net.
travel/<slug>/derived/manifest.json drives responsive <img> output (srcset, LQIP, lazy) via _plugins/image_url_processor.rb. Upload it with aws s3 sync to italy/derived/manifest.json on the bucket. With storage_prefix: "yandex", Jekyll fetches that file from Object Storage at build time (falls back to the local copy if the download fails). Video {% include video.html %} paths still need full cloud URLs unless you extend the Jekyll plugin.
The site is configured for GitHub Pages deployment using the jgd gem:
# Deploy to GitHub Pages
bundle exec jgd- OPTIMIZATION.md - Detailed technical documentation
- CLAUDE.md - AI assistant development guidelines
- Jekyll Documentation - https://jekyllrb.com/docs/
- Fork the repository
- Create a feature branch
- Make your changes
- Test locally with
bundle exec jekyll serve - Submit a pull request
This project is open source. Feel free to use it as inspiration for your own travel blog.
Visit the live blog at: https://2xiaomao.ru
Built with β€οΈ using Jekyll and modern web technologies