This tool converts a Ghost blog export to a format compatible with Next.js blogs, particularly those using the Tailwind Nextjs Starter Blog template. It leverages either the Claude AI or ChatGPT API for content processing and formatting.
git clone https://github.com/aiconsultancy/ghost-to-nextjs-blog-converter.git
cd ghost-to-nextjs-blog-converter
npm install
Before running the converter, set up the config.yaml
file. Here's an example configuration:
# Ghost to Next.js Blog Converter Configuration
# Input configuration
input:
# Type of input (currently only supports 'ghost')
type: ghost
# Path to the Ghost export JSON file
path: ./ghost-export.json
# Output configuration
output:
# Directory where converted MDX files will be saved
directory: "./data/blog"
# Ghost-specific configuration
ghost:
# Base URL of the original Ghost blog
url: "https://www.yourdomain.com"
# Whether to include '/blog/' prefix in canonical URLs
include_blog_prefix: false
# Image handling configuration
images:
# Directory where downloaded images will be saved
output_directory: "./public/static/images"
# List of image file extensions to process
extensions:
- ".jpg"
- ".jpeg"
- ".png"
- ".gif"
- ".svg"
remove_failed: true # Whether to remove failed image downloads from content
rename_downloaded: true # Whether to rename downloaded images to match the alt text set by Claude
# AI service configuration
ai_service:
provider: "chatgpt" # Options: "claude" or "chatgpt"
claude:
api_key: "your_claude_api_key_here"
model: "claude-3-5-sonnet-20240620"
max_tokens: 5000
max_retries: 5
initial_retry_delay: 1000 # in milliseconds
chatgpt:
api_key: "your_chatgpt_api_key_here"
model: "gpt-4o"
max_retries: 5
initial_retry_delay: 1000 # in milliseconds
# Conversion process configuration
process:
posts_to_process: 0 # Set to 0 to process all posts, or specify a number to limit the posts processed
rate_limit_delay: 2000
# Logging configuration
logging:
# Logging level (e.g., 'info', 'warn', 'error')
level: info
# Path to the log file
file: conversion.log
Before running the converter, set up the config.yaml
file. Adjust the settings according to your needs:
ghost.url
to match your Ghost blog's URL.input.path
to your Ghost export JSON file.output.directory
where you want the converted files to be saved.images.output_directory
to ./public/static/images
ai_service.provider
(either "claude" or "chatgpt") and provide the corresponding API key.your_api_key_here
with your actual Claude AI API key or your_chatgpt_api_key_here
with your actual ChatGPT API key (depending on which AI service you are using).process.rate_limit_delay
if needed to comply with API rate limits.images.extensions
list if you need to handle additional image types.Export your Ghost blog content:
Place the exported JSON file in the same directory as the ghost-to-nextjs-converter.js
script and update the input.path
in config.yaml
accordingly.
Install dependencies (if you haven't already):
npm install
Run the converter:
npm run convert
The converted MDX files and images will be saved in the specified output directory.
The converter will create MDX files in the output directory and save images in the public/static/images directory:
./data/blog/<post-slug>.mdx
./public/static/images/<post-slug>/<filename>.<ext>
The frontmatter structure will be compatible with the Tailwind Nextjs Starter Blog, including fields such as title, date, tags, draft status, summary, and image references.
---
title: "Example Post"
date: "2024-02-20"
tags: ["example", "post"]
draft: false
summary: "This is a summary of the post."
images: []
canonicalUrl: "https://example.com/example-post"
---
---
title: "Example Post with Banner"
date: "2024-02-21"
tags: ["example", "featured"]
draft: false
summary: "This is a summary of the post with a banner image."
images: ["/static/images/example-post-with-banner/featured-image.jpg"]
canonicalUrl: "https://example.com/example-post-with-banner"
layout: "PostBanner"
---
Note the following details:
images
field is always an array, even if there's only one image or no images.layout
will be set to 'PostBanner' and the feature image will be the first in the images
array.images
array as the banner image when the layout is set to 'PostBanner'.layout
will be set to 'PostLayout'.ghost.url
in the config file is correct, as the script uses this in replacement of __GHOST_URL__ which is exported from Ghost.conversion.log
file for detailed information about the conversion process and any errors encountered.Contributions are welcome! Please feel free to submit a Pull Request.
This project is open source and available under the MIT License.