The scariest moment is just before you leave the save room.

Overview and main features of this blog site

#Development

This article was machine-translated. Read the original (日本語)

In a nutshell

This is a multilingual blog platform about my private life and software development. A single article can be published in up to five languages ​​(English, Japanese, Russian, German, and French), and while machine translation is treated as "first-class citizen," it's based on a workflow where every article is reviewed and finalized by a human.

Furthermore, the design prioritizes operating within the free tier of cloud services, almost at zero cost, and being portable and easily migrated to another service at any time.

The blog's name is "The Save Room". Gamers might recognize it. The background of the homepage features a certain police station, standing amidst the night mist and rain of Raccoon City (Claude drew everything from scratch with CSS, without borrowing other people's art). I intend to use this as neo-diary — a modern-day journal — for a long time.

Note that "Like" and comment" functions are intentionally not implemented. This is a place for quiet writing.


Two Essential Systems

This project has two applications within a single repository.

Application Role
Public Site (Web) The side where readers visit and see articles. Multilingual support.
Admin Console (Console) The side used only by me, for writing articles. Authenticated editor, translation, upload, tag/link management, export.

Both share the same "article data" and "body rendering mechanism." Therefore, the console's preview screen matches the public site's appearance down to the pixel, due to its design. What you see while writing is exactly how it will be published.

--

Main Features

1. Multilingual Content Model

Each article has a structure where up to five lines of "translation" for each language are attached to one line of "article body." Each language can be drafted/published independently.

  • It can naturally express situations like "published in English only, Japanese still in draft."

  • An article will only appear on the site in a given language if a "published translation" exists in that language. This is not a UI rendering logic, but is guaranteed at the database query level. Therefore, it is theoretically impossible for an "unfinished translation to accidentally appear."

2. Machine Translation + Human Review

One can machine translate an article written in the base language into any combination of the other four languages ​​with a single button click. The translated text is saved as a "draft with a machine translation flag," and if you manually correct it, it will be marked as "edited." (At present, the "edited" flag is only displayed in the editor console).

The most important thing we focused on here was "masking that doesn't break during translation." Before passing the text to the translation API, code blocks, inline code, custom shortcodes, and Markdown link URLs are temporarily replaced with special symbolic tokens. Once the translation is returned, they are restored to their original form. Thanks to this design, Markdown structure and symbols pass through machine translation without a single byte being corrupted (verified using the actual Google Translate API).

3. Rich Body Text ── Shortcodes

While the body text is written in Markdown, missing elements can be embedded using a unique notation called "shortcodes."

Notation Effects
{{image}} Insert image (the next unused image, or a specified image)
{{gallery 3}} Create a carousel with the next 3 images that can be swiped
{{youtube <id> t=1m30s}} Embed YouTube video that doesn't load until clicked (with specified start position)
{{pdf}} Inline PDF preview + download link
{{audio}} Audio player
{{video}} Video player
{{link <key> text="ラベル"}} Links that display different URLs depending on the display language

This system is designed as a "registry," and adding a new embed type only requires writing one renderer. No database changes are necessary. In fact, audio and video were added to this system later.

4. Writing Console

  • Markdown editor with language tabs. Live preview updates with a 400ms delay.
  • Media Panel: Upload multiple files at once via drag and drop, with progress display. Includes alt text editing, sorting, and cover image selection.
  • Images and PDFs are uploaded via the server. Images are limited to a maximum of 2000px on the longest side, generating 400px thumbnails. Animated GIFs are uploaded as is.
  • Audio and video are uploaded directly to cloud storage from the browser. Large files do not pass through the app's server, avoiding serverless capacity limitations.
  • Tag management (display names per language), per-article link management, slug editing, logical deletion (trash and restore), full-text title search, and paging.
  • One-click export: Outputs all tables as JSON and a ZIP file containing all files on your host. This is an escape hatch for "migrating anytime."

5. Public Site

  • Language detection is performed in the following order: URL → Cookie → Browser language settings → English.

  • Article pages are fully rendered using a shared pipeline: sanitized Markdown, swipeable image carousel, click-to-load YouTube videos, PDF preview, custom audio player, seekable videos, and language-specific links.

  • Machine-translated pages display a "This is a machine translation" note and a link to the original text.

  • The layout is mobile-first. The sidebar (avatar, language switch, tag list) collapses into a hamburger menu on smartphones. The header displays rotating quotes for each language.