From d17320d0d27a9f36932fe07596cf5b28603e792c Mon Sep 17 00:00:00 2001 From: system_master Date: Sun, 2 Nov 2025 12:16:34 +0900 Subject: [PATCH] =?UTF-8?q?=E3=82=B3=E3=83=B3=E3=83=86=E3=83=B3=E3=83=84?= =?UTF-8?q?=E9=81=B7=E7=A7=BB=E3=83=AA=E3=83=B3=E3=82=AF=E7=94=9F=E6=88=90?= =?UTF-8?q?=E3=81=A8html=E3=83=87=E3=82=B3=E3=83=BC=E3=83=89=E5=87=A6?= =?UTF-8?q?=E7=90=86=E3=81=AE=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/news/NewsCard.tsx | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/components/news/NewsCard.tsx b/src/components/news/NewsCard.tsx index 22c4c1a..8a76358 100644 --- a/src/components/news/NewsCard.tsx +++ b/src/components/news/NewsCard.tsx @@ -9,18 +9,35 @@ import type { NewsItem } from "@/types/news"; const stripTags = (html?: string | null) => (html ? html.replace(/<[^>]+>/g, "") : ""); +// HTMLエンティティをデコード +const decodeEntities = (text: string) => { + const textarea = document.createElement("textarea"); + textarea.innerHTML = text; + return textarea.value; +}; + export default function NewsCard({ item }: { item: NewsItem }) { const summary = useMemo(() => { if (!item.content) return ""; - const plain = stripTags(item.content); + const plain = decodeEntities(stripTags(item.content)); return plain.length > 80 ? plain.slice(0, 80) + "…" : plain; }, [item.content]); - const href = - item.linkurl && item.linkurl !== "" - ? item.linkurl - : item.content - ? `/news/${item.id}` - : null; + const href = (() => { + const url = item.linkurl?.trim(); + + // リンクなし(none/空)の場合は詳細ページへ + if (!url || url.toLowerCase() === "none") { + return `/news/${item.id}`; + } + + // 外部URLはそのまま + if (/^https?:\/\//i.test(url)) { + return url; + } + + // 内部スラッグ(相対指定)の場合 + return `/news/${url}`; + })(); const target = item.link_target === "_blank" ? "_blank" : "_self"; const isExternal = href?.startsWith("http");