iTranslated by AI
Building a Data Conversion Website: From SEO Design to npm Publishing
Introduction
I built a static site that handles JSON, YAML, and CSV conversion entirely within the browser. From tech stack selection and SEO design to implementing a blog feature and publishing a CLI package to npm, I did the whole process and am documenting it here.
Website: https://formatarc.com
CLI: https://github.com/m-naoki-m/formatarc
Why I built it
During development, there are frequent moments where I need to format API responses or convert YAML to JSON. While there are existing online tools, many are cluttered with ads or have architectures that send user data to a server, making me hesitant to paste sensitive work data.
My starting point was the idea that if I created a "conversion tool that runs entirely within the browser," I could host it publicly and capture search traffic.
Tech Stack
- Next.js (App Router, completely static output via
output: "export") - TypeScript
- AWS S3 + CloudFront (deployed via CDK)
- yaml library (YAML parsing)
- PapaParse (CSV parsing)
The key is the completely static file output using output: "export". There is no server-side processing at all; I simply host the HTML/JS/CSS files on S3 and serve them via CloudFront. The running cost is near zero.
Site Structure
I prepared four tools as independent pages.
| Tool | URL Path |
|---|---|
| JSON Formatter | /ja/json-formatter/ |
| YAML → JSON | /ja/yaml-to-json/ |
| JSON → YAML | /ja/json-to-yaml/ |
| CSV → JSON | /ja/csv-to-json/ |

Each tool page shares the same workspace component, configured to follow a 3-step process: Input → Execute → Output.
Internationalization (i18n)
I toggle between ja and en using dynamic segments in app/[locale]/. Instead of separating i18n strings into different files, I included everything as a TypeScript object in lib/site.ts. The project scale doesn't warrant a system for loading JSON files, so this approach is sufficient.
hreflang tags are automatically generated in the buildMetadata function, linking the Japanese and English pages to each other.
SEO Design
Since the primary user flow for a tool site is "find via search → use the tool," I was very mindful of SEO.
What I did
- Canonical URL + hreflang on every page
- BreadcrumbList + FAQPage JSON-LD on tool pages
- OG images (1200x630) set for all pages
- URL normalization with
trailingSlash: true - sitemap.xml output including all pages and all blog posts
Why I built a blog
Tool pages alone limit the range of search keywords. I wanted to create a structure where I can capture traffic via informational keywords like "JSON Parse Error cause" or "Difference between YAML and JSON," and then guide users from those articles to the tool pages.
For the blog, I used a format where Markdown files are placed in content/blog/. I parse the frontmatter with gray-matter and convert content to HTML using remark + remark-html. The following is automatically generated for each article:
- Article + BreadcrumbList JSON-LD
- Table of Contents (extracted automatically from h2/h3 tags)
- hreflang (Japanese/English pairs)
- og:image (from the
imagefield in the frontmatter)

Internal Linking Design
By writing relatedTool: "json-formatter" in an article's frontmatter, it is automatically displayed as a related article on the tool page's sidebar. Conversely, the top page displays the 3 latest articles.
Educational Article → Practical Article → Tool Page
↑ ↓
Top Page ←← Blog List
With this bidirectional linking, users can navigate to other pages regardless of where they enter.
Publishing the CLI to npm
I refactored the site's conversion logic (lib/tooling.ts) to be locale-independent and published it as an npm package with a CLI.
npx formatarc json-format '{"a":1}'
GitHub repository: https://github.com/m-naoki-m/formatarc
Since making the entire site open source would eliminate monetization potential, I adopted an "open core" strategy by isolating only the conversion logic.
- Public: Conversion logic + CLI (MIT License)
- Private: Site UI, SEO design, infrastructure configuration
I have included a link from the GitHub README to the web version.
Deploying the Static Site
I built the S3 bucket and CloudFront distribution using CDK. Deployment is simply an aws s3 sync to upload differences, followed by invalidating the CloudFront cache.
npm run build # Generates static files in out/
npm run deploy # S3 sync + CloudFront invalidation
Retrospective
What went well
- The static output via
output: "export"makes deployment simple and clean. - Markdown blogging means adding articles only requires creating a file.
- The
relatedToolmechanism automated the linking between articles and tools.
Challenges
- Generating anchor IDs from blog headings doesn't handle Japanese slugs well (resulting in IDs like
json-整形とは). - Since I'm using static output, I cannot dynamically generate OG images, so I'm relying on default images with manual settings per article.
Summary
- You can operate a conversion site with near-zero running costs by using Next.js static output + S3/CloudFront.
- For SEO, incorporating structured data, hreflang, and internal linking design from the beginning makes things easier later.
- An "open core" approach—where only the core conversion logic is open source—is well-suited for individual development.
Website: https://formatarc.com
GitHub: https://github.com/m-naoki-m/formatarc
npm: https://www.npmjs.com/package/formatarc
Discussion