Migration Tools
Neutrino includes powerful tools to help you migrate content from other platforms and content management systems. These tools are designed to be standalone, configurable, and easy to use.
Available Tools
Legacy Content Importer
The Legacy Content Importer is a comprehensive tool that converts content from various platforms into Neutrino's ULID-based system.
Features:
- Automatic ULID generation for all content
- Flexible frontmatter field mapping
- Slug generation from titles
- SEO-friendly alias creation
- Image path handling and conversion
- Backup functionality before import
- Dry-run mode for safe testing
- Support for multiple content sources
Quick Start
1. Install Dependencies
cd tools/legacy-content-importernpm install
2. Configure the Tool
Copy the example configuration and customize it for your needs:
cp config.example.yml my-config.yml
3. Test the Import
Always test with dry-run mode first:
npm run tools:import:config:dry
4. Run the Import
When you're satisfied with the test results:
npm run tools:import:config
Supported Platforms
Jekyll
source: "./_posts"target: "./src/content/posts"author: "Your Name"fieldMappings: title: ["title"] description: ["excerpt"] date: "date" tags: "tags" category: "categories"
Hugo
source: "./content/posts"target: "./src/content/posts"author: "Your Name"fieldMappings: title: ["title"] description: ["description"] date: "date" tags: "tags" category: "categories"
Ghost
source: "./ghost-export/posts"target: "./src/content/posts"author: "Your Name"fieldMappings: title: ["title"] description: ["excerpt"] date: "published_at" tags: "tags"
WordPress
For WordPress, first export your content to markdown using a plugin like "WP Markdown Exporter", then:
source: "./wordpress-export"target: "./src/content/posts"author: "Your Name"fieldMappings: title: ["post_title"] description: ["post_excerpt"] date: "post_date" tags: "post_tags" category: "post_category"
Configuration Options
Basic Configuration
# Source and target directoriessource: "./old-blog"target: "./src/content/posts"
# Default valuesauthor: "Your Name"imagePath: "/img/"
# Field mappingsfieldMappings: title: ["page-title", "seoTitle", "title"] description: ["descrizione", "description", "excerpt"] date: "date" tags: "tags" category: "category" image: "image" author: "author" draft: "draft" featured: "featured" type: "type"
# Content processingcontent: addCategoryToTags: true createAliases: true aliasPattern: "/blog/{slug}/"
# Backup settingsbackup: enabled: true directory: "backup-before-import"
Advanced Configuration
Custom Field Mappings
You can map any legacy field to any Neutrino field:
fieldMappings: title: ["post_title", "title", "headline"] description: ["meta_description", "excerpt", "summary"] customField: "legacy_custom_field"
Multiple Title Sources
The tool will try each field in order until it finds a value:
fieldMappings: title: ["page-title", "seoTitle", "title", "headline"] description: ["descrizione", "description", "excerpt", "summary"]
Custom Alias Patterns
Create custom URL patterns for aliases:
content: aliasPattern: "/old-blog/{slug}/" # Custom pattern # or aliasPattern: "/archive/{year}/{month}/{slug}/" # Date-based pattern
Command Line Usage
Basic Commands
# Show helpnode index.js --help
# Dry run with parametersnode index.js --source ./old-blog --target ./src/content/posts --dry-run
# Real import with parametersnode index.js --source ./old-blog --target ./src/content/posts
# Use configuration filenode index.js --config my-config.yml --dry-runnode index.js --config my-config.yml
Advanced Options
# Custom author and image pathnode index.js \ --source ./old-blog \ --target ./src/content/posts \ --author "Your Name" \ --image-path "/assets/images/" \ --verbose
# Disable backupnode index.js \ --source ./old-blog \ --target ./src/content/posts \ --no-backup
Best Practices
1. Always Test First
# Always run dry-run firstnpm run tools:import:config:dry
2. Backup Your Data
The tool creates automatic backups, but you should also:
# Create your own backupcp -r src/content/posts src/content/posts-backup
3. Review the Results
After import, check:
- All content was imported correctly
- ULIDs were generated properly
- Slugs are URL-friendly
- Images are accessible
- Aliases work for old URLs
4. Test Your Site
# Build and test your sitenpm run buildnpm run dev
5. Update Internal Links
After migration, you may need to update internal links in your content to use the new ULID-based URLs.
Troubleshooting
Common Issues
"Source directory not found"
Make sure the source path is correct and accessible:
# Check if directory existsls -la ./old-blog
# Use absolute path if needednode index.js --source "/full/path/to/old-blog" --target ./src/content/posts
"No markdown files found"
Ensure your source directory contains .md
files:
# Check for markdown filesfind ./old-blog -name "*.md" | head -10
"Target directory already exists"
The tool won't overwrite existing content. Either:
- Use a different target directory
- Remove existing content first
- Use the
--force
flag (if available)
"Field mapping errors"
Check your configuration file for typos in field names:
# Make sure field names match exactlyfieldMappings: title: ["title"] # Not "Title" or "TITLE"
Getting Help
- Check the tool's README:
tools/legacy-content-importer/README.md
- Run with
--help
flag:node index.js --help
- Use verbose mode:
node index.js --verbose
- Check the project's GitHub issues
Contributing
To contribute to migration tools:
- Fork the repository
- Create a feature branch
- Add your tool to the
tools/
directory - Follow the tool requirements in
tools/README.md
- Submit a pull request
License
Migration tools are licensed under the same MIT license as Neutrino.