From fc5f41b9cc9ee66b456df1b8875f4eb2a42502ab Mon Sep 17 00:00:00 2001 From: zenn Date: Sun, 3 May 2026 10:03:53 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B2=8C=EC=8B=9C=EB=AC=BC=20SEO=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/admin/AdminPostForm.vue | 72 +++++++++++++++++++++++ db/migrations/008_add_post_seo_fields.sql | 11 ++++ docs/history.md | 8 +++ docs/map.md | 5 +- docs/spec.md | 7 +++ docs/todo.md | 1 - docs/update.md | 8 +++ package-lock.json | 4 +- package.json | 2 +- pages/post/[slug].vue | 38 ++++++++++++ server/repositories/content-repository.js | 16 +++++ server/utils/admin-post-input.js | 4 ++ server/utils/content-schema.js | 4 ++ 13 files changed, 174 insertions(+), 6 deletions(-) create mode 100644 db/migrations/008_add_post_seo_fields.sql diff --git a/components/admin/AdminPostForm.vue b/components/admin/AdminPostForm.vue index b7ba17d..1d59548 100644 --- a/components/admin/AdminPostForm.vue +++ b/components/admin/AdminPostForm.vue @@ -74,6 +74,10 @@ const form = reactive({ excerpt: props.initialPost.excerpt || '', content: props.initialPost.content || '', featuredImage: props.initialPost.featuredImage || '', + seoTitle: props.initialPost.seoTitle || '', + seoDescription: props.initialPost.seoDescription || '', + canonicalUrl: props.initialPost.canonicalUrl || '', + noindex: Boolean(props.initialPost.noindex), status: props.initialPost.status || 'draft', publishedAt: toDateTimeLocalValue(props.initialPost.publishedAt), tagsText: props.initialPost.tags?.join(', ') || '' @@ -144,6 +148,10 @@ const createPostPayload = () => { excerpt: form.excerpt.trim(), content: form.content, featuredImage: form.featuredImage.trim() || null, + seoTitle: form.seoTitle.trim(), + seoDescription: form.seoDescription.trim(), + canonicalUrl: form.canonicalUrl.trim(), + noindex: form.noindex, status: form.status, publishedAt, tags: parseTags(form.tagsText) @@ -160,6 +168,10 @@ const createAutosavePayload = () => ({ excerpt: form.excerpt, content: form.content, featuredImage: form.featuredImage, + seoTitle: form.seoTitle, + seoDescription: form.seoDescription, + canonicalUrl: form.canonicalUrl, + noindex: form.noindex, status: form.status, publishedAt: form.publishedAt, tagsText: form.tagsText @@ -476,6 +488,66 @@ defineExpose({ > +
+
+

+ SEO +

+

+ 검색 결과와 공유 미리보기에 사용할 기본 메타 정보를 설정합니다. +

+
+ + + +