Migrate your existing static site to Bengal. Whether you're coming from Hugo, Jekyll, Gatsby, or another SSG, these steps help you preserve your content and URLs.
When to Use This Guide
- You have an existing site built with another static site generator
- You want to preserve your content structure and URLs
- You need to convert frontmatter formats
- You want to maintain your site's SEO and link structure
Prerequisites
Before You Begin
- Bengal installed
- Access to your existing site's source files
- Basic knowledge of Markdown and YAML/TOML
Steps
- 1
Create Your Bengal Site
Initialize a fresh Bengal project as your migration destination.
Start by creating a new Bengal site:
1 2
bengal new site mysite cd mysiteChoose Blank preset if you're migrating existing content, or select a preset that matches your site type.
- 2
Understand Content Structure Differences
Learn how Bengal's file-system routing compares to your current SSG.
File Organization
Bengal uses file-system routing where the
content/directory structure directly maps to URLs:SSG Content Location Bengal Equivalent Hugo content/content/Jekyll _posts/,_pages/content/blog/,content/Gatsby src/pages/content/Next.js pages/content/Index Files
Bengal distinguishes between section and page index files:
_index.md- Creates a section (folder that can contain pages)index.md- Creates a page in its own folder
This is different from Hugo's
_index.md(always a section) and Jekyll'sindex.html(always a page). - 3
Convert Frontmatter
Adapt your frontmatter fields to Bengal's conventions.
From Hugo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
# Hugo frontmatter --- title: "My Post" date: 2023-10-25 draft: false tags: [python, web] categories: [tutorial] slug: my-post weight: 10 --- # Converted to Bengal --- title: My Post date: 2023-10-25 draft: false tags: [python, web] category: tutorial # Note: singular, not plural slug: my-post weight: 10 ---Key differences:
categories(plural) →category(singular) in Bengal- Remove quotes from simple string values
- Date format remains the same (ISO format)
From Jekyll
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
# Jekyll frontmatter --- layout: post title: "My Post" date: 2023-10-25 14:30:00 +0000 categories: [tutorial, python] tags: [web] published: true --- # Converted to Bengal --- type: post # layout → type title: My Post date: 2023-10-25T14:30:00Z # Convert to ISO format category: tutorial # Use first category tags: [web] draft: false # published: true → draft: false ---Key differences:
layout→typein Bengal (see Component Model: Type)published: true→draft: falsecategories→category(use first category)- Date format: Convert to ISO format
From Gatsby/MDX
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
# Gatsby frontmatter --- title: "My Post" date: "2023-10-25" author: "John Doe" tags: ["python", "web"] featured: true --- # Converted to Bengal --- title: My Post date: 2023-10-25 author: John Doe tags: [python, web] # featured can be stored in params or custom frontmatter --- - 4
Migrate Content Files
Copy and convert your existing content to Bengal format.
Automated Migration Script
Create a simple Python script to help with bulk conversion:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
#!/usr/bin/env python3 """Convert Hugo/Jekyll content to Bengal format.""" import re from pathlib import Path def convert_frontmatter(content: str, source_format: str = "hugo") -> str: """Convert frontmatter from source format to Bengal.""" # Extract frontmatter frontmatter_match = re.match(r'^---\n(.*?)\n---\n', content, re.DOTALL) if not frontmatter_match: return content frontmatter = frontmatter_match.group(1) body = content[frontmatter_match.end():] # Convert categories to category (singular) frontmatter = re.sub(r'categories:\s*\[(.*?)\]', r'category: \1', frontmatter) # Convert published to draft if 'published: true' in frontmatter: frontmatter = frontmatter.replace('published: true', 'draft: false') elif 'published: false' in frontmatter: frontmatter = frontmatter.replace('published: false', 'draft: true') # Remove quotes from simple strings frontmatter = re.sub(r'"(.*?)"', r'\1', frontmatter) return f"---\n{frontmatter}\n---\n{body}" # Usage source_dir = Path("path/to/hugo/content") target_dir = Path("content") for md_file in source_dir.rglob("*.md"): content = md_file.read_text() converted = convert_frontmatter(content, source_format="hugo") # Preserve directory structure relative_path = md_file.relative_to(source_dir) target_file = target_dir / relative_path target_file.parent.mkdir(parents=True, exist_ok=True) target_file.write_text(converted) print(f"Converted: {md_file} → {target_file}")Manual Migration Steps
Copy content files:
1 2 3 4 5 6
# From Hugo cp -r /path/to/hugo/content/* content/ # From Jekyll mkdir -p content/blog cp -r /path/to/jekyll/_posts/* content/blog/Rename index files:
1 2
# Hugo _index.md → Bengal _index.md (same) # Jekyll index.html → Bengal index.mdConvert frontmatter:
- Use the script above or convert manually
- Check each file for format-specific fields
- 5
Preserve URLs
Maintain SEO and prevent broken links during migration.
Bengal generates URLs from file paths. To preserve existing URLs:
Use
slugfrontmatter to override generated URLs:1 2 3 4
--- title: My Post slug: /old/url/path # Preserves old URL structure ---Create redirects (if URLs must change):
1 2 3 4 5
# content/old-url.md --- title: Redirect redirect: /new-url/ ---Check URL generation:
1 2
bengal build # Check public/ directory for generated URLs
- 6
Migrate Assets
Move images, CSS, JS, and other static files to Bengal's asset directories.
Bengal looks for assets in:
assets/- Site-specific assetsthemes/[theme-name]/static/- Theme assets
Migration steps:
Copy static files:
1 2 3 4 5
# From Hugo cp -r /path/to/hugo/static/* assets/ # From Jekyll cp -r /path/to/jekyll/assets/* assets/Update image references:
- Hugo:
→ - Jekyll:
→
- Hugo:
Update CSS/JS references:
- Move to
assets/css/andassets/js/ - Update template references if using custom themes
- Move to
- 7
Migrate Configuration
Convert your SSG's config file to Bengal's YAML configuration system.
From Hugo
config.toml1 2 3 4 5 6 7 8 9 10
# Hugo config.toml baseURL = "https://example.com" title = "My Site" languageCode = "en-us" # Converted to Bengal bengal.toml [site] baseurl = "https://example.com" title = "My Site" language = "en"From Jekyll
_config.yml1 2 3 4 5 6 7 8 9 10
# Jekyll _config.yml title: My Site url: https://example.com lang: en # Converted to Bengal bengal.toml [site] title = "My Site" baseurl = "https://example.com" language = "en"Menu Configuration
1 2 3 4 5 6 7 8 9 10
# Bengal menu structure [[site.menu.main]] name = "Home" url = "/" weight = 1 [[site.menu.main]] name = "Blog" url = "/blog/" weight = 2 - 8
Test Your Migration
Verify your content renders correctly and links work.
Verification Steps
- Build the site:
bengal build - Check for errors:
bengal build --verbose - Validate links:
bengal health linkcheck - Preview locally:
bengal serve(visit http://localhost:5173)
- Build the site:
- 9
Handle Special Cases
Address shortcodes, taxonomies, and data files that need manual conversion.
Taxonomies
Bengal uses
tagsandcategory(singular) for taxonomies:1 2 3
# Convert multiple categories to tags # Hugo: categories: [tutorial, python] # Bengal: category: tutorial, tags: [python]Shortcodes
Bengal doesn't have Hugo-style shortcodes. Options:
Convert to Markdown:
1 2 3 4 5
# Hugo shortcode {{< youtube id="dQw4w9WgXcQ" >}} # Bengal: Use HTML or Markdown <iframe src="https://www.youtube.com/embed/dQw4w9WgXcQ"></iframe>Use Jinja2 templates (for advanced cases)
Data Files
Bengal doesn't have Jekyll-style
_data/files. Options:Move to
config/params.yaml:1 2 3 4
# config/params.yaml authors: - name: John Doe email: john@example.comUse Python scripts to generate content from data
Troubleshooting
Common Issues
Frontmatter parsing errors:
- Check YAML syntax (proper indentation, no tabs)
- Verify date formats (use ISO format:
2023-10-25) - Remove unsupported fields
Missing pages:
- Check if files are in
content/directory - Verify
_index.mdvsindex.mdusage - Check for
draft: true(excluded from builds)
Broken links:
- Run
bengal health linkcheckto find broken links - Update internal links to use relative paths
- Check URL generation matches expectations
Assets not loading:
- Verify assets are in
assets/directory - Check image paths in content (use relative paths)
- Ensure asset references match Bengal's structure
:::
Getting Help
- Check Content Organization for structure details
- Review Configuration for config options
- See Get Started for basics
Next Steps
- Content Authoring - Learn Bengal's content features
- Theming - Customize your site's appearance
- Deployment - Deploy your migrated site