article
投稿フォーマットの選び方
tiptap、markdown、html、static の四つの format と `metadata.no_layout`。同じ投稿モデルのまま、普通の記事からデザイナー納品の LP まで扱うための選び方です。
ampless の投稿(Post)は、モデルそのものは 1 種類のままです。format の四つの値(tiptap / markdown / html / static)と metadata.no_layout のフラグを掛け合わせることで、五通りの公開挙動をひとくくりに扱えるようにしてあります。リッチエディタで書いた読み物も、デザイナーから渡された完成 HTML も、AI エージェントが流し込んだ Markdown も、同じ slug 体系の上に自然に並んでいきます。
公開挙動を決める要素は、次の四つです。
| 設定 | 場所 | 効果 |
|---|---|---|
format |
エディター | 本文の保存・解釈方法(tiptap / markdown / html / static) |
metadata.no_layout |
format: 'html' のときのみ表示 |
本文をそのまま返し、テーマのクロームを被せない |
metadata.cache |
auto / deep / hot |
投稿ごとのキャッシュ戦略を上書き |
status / slug / publishedAt |
エディター | 公開可否と URL |
tiptap
リッチテキストエディタの構造化ドキュメントとして保存する形です。ブログ記事を書き始めるなら、ここから入るのがいちばん素直になります。
- 見出し、リスト、リンク、画像、コード、引用、表、タスクリストに対応
- 本文は JSON ノードツリー(
{ type: 'doc', content: [...] })として DynamoDB に保存 - 公開時は、ランタイム側でリクエストごとに HTML(あるいは React の ReactNode)として描画
WYSIWYG で手を動かしながら書きたい場面では、これを選びます。
markdown
プレーンテキストエリアに、Markdown ソースをそのまま流し込む形です。GFM(テーブル、フェンス、タスクリストなど)も有効になっています。
- 開発者向け、git push 派の運用と相性が良い
- MCP 経由で AI エージェントに記事を書いてもらうときも、Markdown だといちばん扱いやすい
- canonical は文字列としてそのまま保管し、描画時に HTML へ変換
- ちなみにこの記事自体も
format: 'markdown'で書いてあります
html
プレーンテキストエリアに、生の HTML を貼り込む形です。本文は サニタイズせず、書いた内容がそのまま出力 されます。
- カスタム HTML やインライン
<style>/<script>を仕込みたい場合 - WordPress 移行組や、HTML を直接書きたい人向け
- editor は信頼済みプリンシパルとして扱う設計です(詳細は mcp-http-transport を参照)
no_layout — ベア HTML
format: 'html' に metadata.no_layout: true を立てた状態の組み合わせです。投稿本文を加工せず、そのまま HTTP レスポンスとして返します。format 自体は html のままで、レイアウトモードだけが切り替わるかたち。
<head>の完全制御、トラッキングピクセル、独自フォント、独自レイアウトなど、テーマと相性が悪いものを置きたいときに向きます- middleware が
/<slug>リクエストを内部のベア HTML ハンドラ(/raw/<slug>)に書き換えます - Next.js のルートレイアウトも、テーマのクロームも、どちらも被せません
- ブラウザの URL は通常どおり
/<slug>のまま
slug: promo
format: html
metadata:
no_layout: true
body: |
<!DOCTYPE html>
<html lang="ja">
<head>
<title>Promo</title>
<style>body { ... }</style>
</head>
<body>...</body>
</html>
no_layout チェックボックスは format: 'html' のときだけ表示されます。tiptap / markdown ではフラグメントしか返せず、意味を持たないためです。
static — 静的バンドル
HTML / CSS / JS / 画像 / フォントなどをまとめた .zip、もしくは複数ファイルをそのままアップロードして使う format です。
- LP、キャンペーンページ、デザイナー納品のマイクロサイト、他のジェネレーターから書き出した SPA など
- ampless がブラウザ側で zip を展開して、各ファイルを S3(
public/static/<slug>/...)に並べていきます - 公開 URL は
/<slug>で entrypoint、/<slug>/<相対パス>で各ファイル(middleware が/static/<slug>(/...)に書き換えます) - 保存し直すたびに、バンドル全体が置き換わります(マージはしません)
検証時のチェック項目は、わりと厳しめに設定してあります。
- 絶対パス参照(
href="/style.css"、url(/img.png))は弾きます - protocol-relative(
//cdn/foo)、パストラバーサル(../)、null バイトも同じく弾きます - macOS / Windows のメタデータ(
__MACOSX/、.DS_Store、Thumbs.db)は自動で除去
create_post / update_post は format: 'static' を意図的に弾いています。manifest と S3 のズレを防ぐためで、バンドル管理は専用ツール(upload_static_bundle / upload_static_file / delete_static_file / commit_static_post)に寄せています。
キャッシュ戦略
metadata.cache の値で、投稿ごとに振る舞いを上書きできます。リクエストごとに middleware が Cache-Control を組み立てて、CloudFront 側に効かせる流れです。
| 値 | 挙動 |
|---|---|
auto(デフォルト) |
直近の編集(既定 1 時間以内)は no-store、それを過ぎると 5 分キャッシュ |
deep |
常に 1 時間キャッシュ。当面動かない解説記事に向きます |
hot |
常に no-store。本文をリクエストごとに計算する、もしくは頻繁に書き換える投稿に向きます |
三つの戦略は、no_layout や format からは独立して動きます。テーマレンダリングでも、no_layout でも、static でも、同じ仕組みで上に乗ってきます。
選び分けの目安
| ケース | format / metadata |
|---|---|
| ブログ記事をエディタで書く | tiptap |
| ドキュメントを git で管理したい | markdown |
| AI エージェントに執筆を任せる | markdown |
| WordPress から HTML を持ち込む | html |
| 独自ヘッダーやトラッキングを仕込んだ単独ページ | html + metadata.no_layout: true |
| デザイナー納品の LP やキャンペーンサイト | static |
slug 自体は共通の名前空間です。/promo をどの方式で配信するかは、後から format や metadata を差し替えるだけで切り替わるので、最初の選択にがちがちに縛られる必要はありません。
関連記事
- ampless の全体像 → what-is-ampless
- 始めるのに用意するもの → getting-started
- サーバレス構成の内訳 → serverless-stack
- MCP 経由の投稿 → mcp-http-transport