ساخت وبلاگ استاتیک دوزبانه با Eleventy: ساختار، سئو و اشتباههای من
برای وبلاگ همین سایت میخواستم چیزی ساده و سریع داشته باشم: هر مقاله یک فایل Markdown، خروجی کاملاً استاتیک، دو زبان فارسی و انگلیسی، و سئوی درست. Eleventy (یا 11ty) برای همین ساخته شده است.
ساختار
src/
fa/posts/*.md ← مقالههای فارسی
en/posts/*.md ← مقالههای انگلیسی
fa/index.njk ← فهرست فارسی (با صفحهبندی)
en/index.njk
_includes/ ← قالبها (base، post)
_data/site.js ← نامها و متنهای مشترک هر زبان
خروجی داخل پوشهی سایت نوشته میشود؛ پس هاست استاتیک نیازی به build ندارد.
هر مقاله یک فایل
بالای فایل Markdown، متادیتا (front matter) میآید:
---
title: "عنوان مقاله"
description: "توضیح یکتا برای نتایج جستجو"
date: 2026-10-24
slug: english-short-slug
altSlug: english-short-slug
tags: [post, tag]
---
یک فایل دادهی مشترک برای هر زبان، آدرس نهایی را از slug میسازد (مثلاً /blog/<slug>/) و آدرس معادل زبان دیگر را از altSlug. همین دو مقدار برای تگهای canonical و hreflang استفاده میشوند.
سئوی هر مقاله
titleوdescriptionیکتا وh1تنها.link rel="canonical"به آدرس خودش.hreflangبرای نسخهی فارسی، انگلیسی وx-default.- Open Graph با تصویر WebP.
- دادهی ساختیافته
BlogPostingوBreadcrumbListبهصورت JSON-LD. - آدرس انگلیسی و کوتاه (slug).
- sitemap و RSS که خودکار ساخته میشوند.
اشتباههایی که خودم کردم
۱. دو نقطه در توضیح. در YAML، مقداری که : دارد باید داخل نقلقول باشد، وگرنه build با خطا تمام میشود. توضیح و عنوان را همیشه در نقلقول بگذارید.
۲. ویرگول فارسی در برچسبها. [غیبت، پیامک] (با «،») یک برچسب میشود، نه دو تا؛ در YAML باید از ویرگول انگلیسی استفاده کرد.
۳. قالبساز، آکولادها را میخورد. Eleventy بهصورت پیشفرض Markdown را با موتور قالب (Nunjucks) هم پردازش میکند؛ پس دو آکولاد باز و بسته دور یک نام (مثل متغیر یک قالب پیام) در یک بلوک کد مقدارش را از دست میدهد و خالی میشود. راهحل: آن بخش را بین دستورهای raw قالبساز بگذارید.
۴. تاریخ شمسی. بهجای ساختن خودکار با ابزار مرورگر، از یک کتابخانهی آزموده (jalaali-js) استفاده کردم و خروجی را با تاریخهای مشخص مقایسه کردم (نکتههای سایت فارسی).
۵. لینکهای شکسته. بعد از هر build، یک اسکریپت ساده همهی href و src داخلی را بررسی میکند که فایل مقصد وجود داشته باشد.
صفحهبندی
Eleventy صفحهبندی داخلی دارد: یک مجموعهی مقالهها و size را بدهید تا صفحههای /blog/، /blog/page/2/ و … ساخته شوند. لینک «بعدی» و «قبلی» را از pagination.href بگیرید.
چه زمانی انتخاب خوبی است؟
وقتی محتوا مقالهای است، تغییرات زیاد داینامیک نیست و میخواهید سرعت و سئوی بالا با هزینهی نزدیک به صفر داشته باشید. اگر کامنت، حساب کاربری یا محتوای شخصیسازیشده لازم است، به یک بکاند یا سرویس جداگانه نیاز دارید.
جمعبندی
یک قالب، یک فایل Markdown برای هر مقاله و چند فایل داده، برای وبلاگ دوزبانه کافی است. بقیهی مراحل سرعت را در این راهنما ببینید.