惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
DataBreaches.Net
V
Vulnerabilities – Threatpost
C
CERT Recently Published Vulnerability Notes
Google DeepMind News
Google DeepMind News
GbyAI
GbyAI
Y
Y Combinator Blog
T
Threatpost
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Project Zero
Project Zero
Engineering at Meta
Engineering at Meta
MongoDB | Blog
MongoDB | Blog
MyScale Blog
MyScale Blog
Security Latest
Security Latest
T
Threat Research - Cisco Blogs
量子位
I
Intezer
Simon Willison's Weblog
Simon Willison's Weblog
C
Cybersecurity and Infrastructure Security Agency CISA
L
Lohrmann on Cybersecurity
L
LINUX DO - 最新话题
The Register - Security
The Register - Security
T
Tailwind CSS Blog
爱范儿
爱范儿
Google DeepMind News
Google DeepMind News
T
Troy Hunt's Blog
Stack Overflow Blog
Stack Overflow Blog
Cloudbric
Cloudbric
S
Secure Thoughts
The GitHub Blog
The GitHub Blog
T
The Blog of Author Tim Ferriss
L
LangChain Blog
Recorded Future
Recorded Future
小众软件
小众软件
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Tor Project blog
人人都是产品经理
人人都是产品经理
F
Full Disclosure
O
OpenAI News
Webroot Blog
Webroot Blog
A
Arctic Wolf
TaoSecurity Blog
TaoSecurity Blog
P
Privacy & Cybersecurity Law Blog
Jina AI
Jina AI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
雷峰网
雷峰网
Microsoft Security Blog
Microsoft Security Blog
H
Heimdal Security Blog
B
Blog RSS Feed
Vercel News
Vercel News

Dallas Lu

邮件服务的域名成功从 SURBL 黑名单移除 网站多语言的设计细节 网站评论系统的目前进展和展望 在公网使用 iptables 转发端口时保留客户端 IP 邮件投递平台 Postal 的使用经验 自建 Postal 完美替代 SendGrid 互联网在崩塌吗,然后呢 网页的打印样式应该怎么写 “茴字的四种写法”之 IP 与域名 怎么伪造 Git 提交的时区 供大众交流的论坛和其它替代产品还是不好用 改编不是照搬 一次排查诡异的网络问题的经历 在 OpenWRT 23 中使用 nftset 配置 Shadowsocks 规则 使用自建 Tabby Web 来同步 Tabby 配置 手动建立自己的 IPv6 Tunnel 服务 在 PVE 手动配置网络及虚拟机 IPv6 公网 在 PVE 中缩小 Ubuntu 虚拟机的磁盘 Beancount 摊销与折旧的使用以及相关插件
在 SvelteKit 应用中使用 JSON-LD
达拉斯・卢 · 2024-05-14 · via Dallas Lu

使用 SvelteKit 可以很轻松地创建 SSR 的网站应用,但是在 SEO 方面,我们需要在页面中添加一些元数据,比如 JSON-LD。本文将介绍如何在 SvelteKit 应用中使用 JSON-LD。

JSON-LD 是什么

JSON-LD 是一种使用 JSON 格式的数据结构,用于描述数据的语义。它是一种用于在网页上添加结构化数据的格式,可以帮助搜索引擎更好地理解网页内容。在 SEO 方面,JSON-LD 是一种非常重要的技术。JSON-LD 定义了一种嵌入式的语法,用于在 HTML 文档中嵌入结构化数据。一般我们使用 Schema.org 提供的数据结构来描述数据。

SvelteKit 中使用 JSON-LD 的现状

SvelteKit 中的 +layout 可以为每个页面添加一个 layout。在 layout 中添加 JSON-LD 数据,可以为整个网站的结构添加结构化数据。在页面中添加 JSON-LD 数据,可以为页面的内容添加结构化数据。但与此同时, +page.svelte 中也可以添加 JSON-LD 数据,用于描述页面的内容。SvelteKit 并不能为我们自动处理二者之间的关系。我们需要手动解决这个问题。

在 SvelteKit 中添加 JSON-LD 数据的实践

我们可以在 +layout.ts 中预先组织 JSON-LD 数据,然后在 +page.svelte 中添加页面的 JSON-LD 数据。这样可以很好地解决 JSON-LD 数据的问题。我们可在 +page.svelte 中加入 JSON-LD 的输出:

<script lang="ts">
    export let data;

    $: ({ ldjson } = data);

    let ldjson = () => {
        let creativeWork = {
            "@context": "https://schema.org",
            "@type": "CreativeWork",
            "name": "Example Creative Work",
            "author": {
                "@type": "Person",
                "name": "Jane Doe"
            }
        };
        return Object.assign({}, ldjson, creativeWork);
    }
</script>

<svelte:head>
    {@html `<script type="application/ld+json">${JSON.stringify(
        json(),
    )}</script>`}
</svelte:head>

其中 ldjson 是来自父级 layout 的通用 JSON-LD 数据,creativeWork 是当前页面的 JSON-LD 数据。我们可以在页面中添加自己的 JSON-LD 数据,然后合并到 ldjson 中。这样就可以很好地解决 JSON-LD 数据的问题。在 +layout.ts 中,可以:

import type { Load } from '@sveltejs/kit';

export const load: Load = async ({ fetch, params, depends, data }) => {

    const ldjson: any = {
        '@context': 'https://schema.org',
    };

    ldjson.issn = '1234-5678';

    return { ldjson };
}

使用 schema-dts

在 TypeScript 中,我们可以使用 Schema 类型定义来描述 JSON-LD 数据。这样可以更好地组织 JSON-LD 数据。我们可以使用由 Google 维护的 schema-dts

npm install -D --save schema-dts

然后在 +page.svelte 中使用:

import type {
    WithContext,
    Article as SchemeArticle,
    Review,
    CreativeWork,
    WebPage,
} from "schema-dts";

let post: any = {};

let json = () => {
    
    let creativeWork: CreativeWork = {
        "@type": "CreativeWork",
        headline: post.title,
        image: post.image,
        datePublished: new Date(post.date).toISOString(),
        url: post.url,
    };

    if (post.authors) {
        let author = post.authors.map((author: any) =>
            Object.assign(
                {
                    "@type": "Person",
                    name: author.name || author.account || author,
                },
                author.url
                    ? {
                          url: author.url,
                      }
                    : {},
            ),
        );
        if (author.length === 1) {
            author = author[0];
        }
        creativeWork.author = author;
    }

    if (post.modified?.date) {
        creativeWork.dateModified = new Date(
            post.modified.date,
        ).toISOString();
    }
    if (post.summary) {
        creativeWork.description = post.summary;
    }

    if (post.aggregateRating) {
        creativeWork.aggregateRating = {
            "@type": "AggregateRating",
            ratingValue: post.aggregateRating.value,
            reviewCount: post.aggregateRating.count,
            bestRating: post.aggregateRating.best || 10,
            worstRating: post.aggregateRating.worst || 1,
        };
    }

    if (post.template == "item") {
        if (post.review) {
            creativeWork = Object.assign(creativeWork, {
                "@type": "Review",
                itemReviewed: {
                    "@type": post.review.item?.type,
                    name: post.review.item?.name,
                    url: post.review.item?.url,
                    image: post.review.item?.image,
                },
                reviewRating: {
                    "@type": "Rating",
                    ratingValue: post.review.rating,
                    bestRating: 10,
                    worstRating: 1,
                },
                reviewBody: post.review.body || post.summary,
            } as Review);
        } else {
            creativeWork = Object.assign(creativeWork, {
                "@type": "Article",
            } as SchemeArticle);
        }
    } else if (post.template == "links") {
        creativeWork = creativeWork as WithContext<CreativeWork>;
    } else if (post.template == "default") {
        creativeWork = Object.assign(creativeWork, {
            "@type": "WebPage",
        } as WebPage);
    } else {
        creativeWork = creativeWork as WithContext<CreativeWork>;
    }

    let schema: WithContext<any> = Object.assign(creativeWork, {
        "@context": "https://schema.org",
    });

    return Object.assign({}, ldjson, schema);
};

结语

在 SvelteKit 应用中使用 JSON-LD 可以帮助搜索引擎更好地理解网页内容。我们可以在 +layout.ts 中预先组织 JSON-LD 数据,然后在 +page.svelte 中添加页面的 JSON-LD 数据。这样可以很好地解决 JSON-LD 数据的问题。我们可以使用 schema-dts 来更好地组织 JSON-LD 数据。这样可以更好地描述数据的语义。我之前写的一些评测文章,也使用了 JSON-LD 数据,在 Google 的搜索结果中已经显示了我给出的评分数据。