Using SvelteKit it is very easy to create web applications with SSR, but for SEO we need to add some metadata like JSON-LD to the page.This article will explain how to use JSON-LD in SvelteKit applications.

What is JSON-LD

JSON-LD is a data structure that uses the JSON format to describe the semantics of data. It is a format used to add structured data to web pages, which helps search engines to better understand the content of web pages. JSON-LD is a very important technique when it comes to SEO. JSON-LD defines an embedded syntax for embedding structured data in HTML documents. Generally we use the data structure provided by to describe the data.

Current Status of JSON-LD Use in SvelteKit

The +layout in SvelteKit adds a layout to each page. Adding JSON-LD data to the layout adds structured data to the structure of the entire site. Adding JSON-LD data to a page adds structured data to the content of the page. But at the same time, JSON-LD data can be added to +page.svelte, which describes the content of the page. SvelteKit doesn't automatically handle the relationship between the two for us automatically, we need to work around this manually.

Practices for adding JSON-LD data to SvelteKit

We can pre-organize the JSON-LD data in +layout.ts and then add the JSON-LD data for the page in +page.svelte. This is a good solution to the problem of JSON-LD data. We can add in +page.svelte the JSON-LD output:

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

    $: ({ ldjson } = data);

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

    {@html `<script type="application/ld+json">${JSON.stringify(

Where ldjson is the generic JSON-LD data from the parent layout and creativeWork is the JSON-LD data for the current page. We can add our own JSON-LD data to the page and merge it into ldjson. This is a good solution to the JSON-LD data problem. In +layout.ts, you can:

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

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

    const ldjson: any = {
        '@context': '',

    ldjson.issn = '1234-5678';

    return { ldjson };

Use schema-dts

In TypeScript, we can use Schema type definitions to describe JSON-LD data.This allows for better organization of JSON-LD data.We can use the schema-dts maintained by Google

npm install -D --save schema-dts

Then use it in +page.svelte:

import type {
    Article as SchemeArticle,
} from "schema-dts";

let post: any = {};

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

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

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

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

    if (post.template == "item") {
        if ( {
            creativeWork = Object.assign(creativeWork, {
                "@type": "Review",
                itemReviewed: {
                reviewRating: {
                    "@type": "Rating",
                    bestRating: 10,
                    worstRating: 1,
                reviewBody: || 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": "",

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


Using JSON-LD in SvelteKit applications can help search engines better understand page content.We can pre-organize the JSON-LD data in +layout.ts and then add the JSON-LD data of the page in +page.svelte.This is a good solution to the problem of JSON-LD data.We can use schema-dts to better organize JSON-LD data. This can better describe the semantics of the data. Some of my previous reviews have used JSON-LD data, and my ratings have been shown in Google search results.