コンテンツ遷移リンク生成とhtmlデコード処理の追加

This commit is contained in:
system_master 2025-11-02 12:16:34 +09:00
parent a8afd4ef48
commit d17320d0d2

View File

@ -9,18 +9,35 @@ import type { NewsItem } from "@/types/news";
const stripTags = (html?: string | null) => (html ? html.replace(/<[^>]+>/g, "") : ""); 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 }) { export default function NewsCard({ item }: { item: NewsItem }) {
const summary = useMemo(() => { const summary = useMemo(() => {
if (!item.content) return ""; if (!item.content) return "";
const plain = stripTags(item.content); const plain = decodeEntities(stripTags(item.content));
return plain.length > 80 ? plain.slice(0, 80) + "…" : plain; return plain.length > 80 ? plain.slice(0, 80) + "…" : plain;
}, [item.content]); }, [item.content]);
const href = const href = (() => {
item.linkurl && item.linkurl !== "" const url = item.linkurl?.trim();
? item.linkurl
: item.content // リンクなしnone/空)の場合は詳細ページへ
? `/news/${item.id}` if (!url || url.toLowerCase() === "none") {
: null; return `/news/${item.id}`;
}
// 外部URLはそのまま
if (/^https?:\/\//i.test(url)) {
return url;
}
// 内部スラッグ(相対指定)の場合
return `/news/${url}`;
})();
const target = item.link_target === "_blank" ? "_blank" : "_self"; const target = item.link_target === "_blank" ? "_blank" : "_self";
const isExternal = href?.startsWith("http"); const isExternal = href?.startsWith("http");