」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 使用 JSON-LD 提升部落格的 SEO:我如何使用結構化資料添加豐富的結果

使用 JSON-LD 提升部落格的 SEO:我如何使用結構化資料添加豐富的結果

發佈於2024-11-07
瀏覽:409

Boost Your Blog’s SEO with JSON-LD: How I Added Rich Results Using Structured Data

Introduction

A few years ago in 2022, I attended SCaLE 19x. For those who are not aware, SCaLE is an acronym which stands for Southern California Linux Expo and is the name of a community-run open-source and free software conference held annually in the greater Los Angeles area.

Among the many talks given, one I attended was titledEnrich Your Enterprise Knowledge Graph with Linked Open Data via JSON-LDand presented by an individual named Jans Aasman. The talk was quite informative and broadly covered how linked open data was used and growing. Linked open data started in the semantic web community many years ago and is a tool which can be used for making web pages understandable by machines.

Subsequently, one interesting thing I learned about from the talk was how linked data could be used to enable developments in artificial intelligence since it can help make documents more understandable for machines. Given the recent advances in AI, the talk served as a good primer, sparking my interest in that area.

Unfortunately, I wasn’t aware of any practical applications for the information at the time. The talk ended with a note that Google uses JSON-LD (JavaScript Object Notation for Linked Data) for product descriptions, but that didn't resonate with me since I wasn't working on anything having to do with search at the time. Since then, I've started a blog and returned to this technology after gaining an interest in search engine optimization.

Understanding JSON-LD

What is JSON-LD? Here's a quote from Wikipedia's JSON-LD definition:

JSON-LD (JavaScript Object Notation for Linked Data) is a method of encoding linked data using JSON.

From what I understand, linked data allows the linking of data entities to each other. For example, one could define a person entity and have it linked to an article entity where the article has an author. One way to make use of JSON-LD is for SEO purposes using type definitions from https://schema.org.

As an example, here is what an ImageObject instance would look like:

{
  "@context": "https://schema.org",
  "@type": "ImageObject",
  "contentUrl": "https://logarithmicspirals.com/some-image.png"
}

From what I remember of Jans Aasman's talk at SCaLE, linked data can be used to buildknowledge graphs for both public and private use. JSON-LD is a tool to make accessing this data very simple by leveraging the simplicity and support of JSON across many programming languages. In the case of this article, JSON-LD helps contribute toGoogle's knowledge graph by providing structured data about the article.

When I first attended the talk, I wasn't working on any projects which could readily benefit from structured data or JSON-LD. However, after starting this blog I came back around to the technology after exploring the Google Search Console. Google and other search engines support certain schemas for enhancing search results. Google provides documentation about this in an article titledStructured data markup that Google Search supports.

Implementing JSON-LD for Rich Results

The first step of implementing JSON-LD for rich results was to connect the structured data markup supported by Google with the content I offer on my blog. Features like carousels for restaurant reviews aren't really something I can make use. That said, I could definitely use breadcrumb, article, and image markup.

As such, I decided to start with article markup. The article markup ended up being the most involved and least rewarding of the three. In this case, rewarding means it shows up in Google Search Console under the enhancements tab.

To start creating the JSON-LD, I looked for a TypeScript package I could install to help. Thankfully, I was able to find the package schema-dts which allows developers to create objects matching schemas from https://schema.org.

After installing the package with npm install schema-dts, I got to work on some refactoring to make it easy to add schemas to various pages.

Blog Post Article Markup

The first thing I did was create a file src/utils/get-schema.ts. In that file, I added the following code:

import type { CollectionEntry } from "astro:content";
import type { BlogPosting, WithContext, Person } from "schema-dts";

const defaultCreatorName = "Logarithmic Spirals";
const defaultCreator: Person = {
  "@type": "Person",
  "name": defaultCreatorName,
  "url": "https://logarithmicspirals.com/about/"
};

const getBlogPostingSchema = (post: CollectionEntry, url: string): WithContext => {
  const { title, description, tags, pubDate, updatedDate, heroImage } = post.data;
  const image = heroImage.src;

  return {
    "@context": "https://schema.org",
    "@type": "BlogPosting",
    "headline": title,
    "description": description,
    "keywords": tags,
    "author": defaultCreator,
    "datePublished": pubDate.toISOString(),
    ...(updatedDate && { "dateModified": updatedDate.toISOString() }),
    "image": image,
    "inLanguage": "en-US",
    "url": url
  };
};

export { getBlogPostingSchema }

The code uses the frontmatter schema I defined when I originally created the site (although it has been modified over time). Note that this code is partially influenced by code from an article titledAdding structured data to blog posts using Astro.

The getBlogPostingSchema can then be used to render the blog post pages using the blog post data.

Next, I had to update the code for my layouts to add the schema to the various pages it needs to be on. To do this, I had to update my base page layout. The base page layout is a custom layout I have defined atsrc/layouts/BasePage.astro. Here's what that looks like:

---
import type { WithContext, Thing, WebPage, WebSite, BreadcrumbList } from "schema-dts";
import BaseHead from "@components/BaseHead.astro";
import Body from "@layouts/Body.astro";

interface Props {
  title: string;
  description: string;
  image?: string;
  hasNavBar?: boolean;
  schema?: Thing;
  breadcrumb?: BreadcrumbList[] | BreadcrumbList;
}

const { title, description, image, hasNavBar, schema, breadcrumb } = Astro.props;

const webSiteSchema: WithContext = {
  "@context": "https://schema.org",
  "@type": "WebSite",
  "name": "Logarithmic Spirals",
  "url": Astro.site?.toString()
};
const webPageSchema: WithContext = {
  "@context": "https://schema.org",
  "@type": "WebPage",
  "url": new URL(Astro.url.pathname, Astro.site)   "/",
  "description": description,
  "isPartOf": webSiteSchema
};

if (breadcrumb) {
  webPageSchema.breadcrumb = breadcrumb;
}

let schemaToUse: Thing = webPageSchema;

if (schema) {
  schema["isPartOf"] = webPageSchema;
  schemaToUse = schema;
}
---



  
    

Note the separation of schema and breadcrumb. I treat those separately since not every page with a schema has a breadcrumb. The most important piece is the injection of the JSON-LD into the page through a script tag in the head of the document.

The article schema then gets passed in through child pages like this:

---
// ...
const schema: BlogPosting = getBlogPostingSchema(
  post,
  new URL(Astro.url.pathname, Astro.site).toString()   "/",
);
---

Breadcrumb Markup

For a while now, my pages have already had breadcrumb navigation elements on the individual blog post and tag pages. However, it looks like Google doesn't quite understand the HTML breadcrumb as well as it does the JSON-LD breadcrumb (note that by HTML I mean plain HTML without embedded structured data).

After adding the breadcrumb markup, I've seen links to my site have changed in Google. Where I once saw trails likehttps://logarithmicspirals.com > blog > website-migration-aws-amplify-to-cloudflare-insights, I now seehttps://logarithmicspirals.com > Blog. While a subtle difference, it shows that Google is paying attention to the newly added structured data.

To implement the breadcrumbs, I first added a new function to src/utils/get-schema.ts:

const getBlogPostBreadcrumbListSchema = (title: string, site?: URL): WithContext => {
  return {
    "@context": "https://schema.org",
    "@type": "BreadcrumbList",
    itemListElement: [
      {
        "@type": "ListItem",
        position: 1,
        name: "Home",
        item: site?.toString(),
      },
      {
        "@type": "ListItem",
        position: 2,
        name: "Blog",
        item: new URL("blog", site)   "/",
      },
      {
        "@type": "ListItem",
        position: 3,
        name: title,
      },
    ],
  };
};

The output of this function creates JSON-LD matching the examples given by Google inBreadcrumb (BreadcrumbList) structured dataand is intended to be used on pages matching this path scheme https://logarithmicspirals.com/blog/{slug}.

Image Markup

Lastly, another opportunity I saw to make use of Rich Results was on the /gallery/ page of my website. To achieve this, I created the following functions in src/utils/get-schema.ts:

const getImageObjectSchema = (imageNode: ImageNode): WithContext => {
  return {
    "@context": "https://schema.org",
    "@type": "ImageObject",
    "contentUrl": imageNode.url,
    "creator": defaultCreator,
    "creditText": defaultCreatorName,
    "copyrightNotice": defaultCreatorName
  };
};

const getImageGallerySchema = (imageNodes: Array): WithContext => {
  return {
    "@context": "https://schema.org",
    "@type": "ImageGallery",
    "image": imageNodes.map(imageNode => getImageObjectSchema(imageNode))
  };
};

The ImageNode type is a custom type I created and looks like this:

export type ImageNode = {
  key: string,
  title: string,
  technical: {
    bodyMake: string,
    bodyModel: string,
    focalLength: string,
    iso: string,
    lensMake: string,
    lensModel: string
  },
  url: string,
  nodeIndex?: number
};

For some better understanding of the ImageNode type, check out this previous article I wrote:Photo Gallery Migration: Gatsby to Astro Follow-Up.

The schema generation is then used like this:

---
// Import the IMAGES constant which is an Array of ImageNodes.
// ...
const schema = getImageGallerySchema(IMAGES);
---

Results and Google Search Console Enhancements

So far, I haven't seen a noticeable increase in traffic through Google Search, but to be fair, my blog is quite niche, and the changes haven't been live for long.

In terms of search appearance, the breadcrumbs are showing up and I've yet to check on the results for the image markup.

The most notable change has been in the Google Search Console where I'm now seeing an Enhancements section with information about the breadcrumbs and images.

Boost Your Blog’s SEO with JSON-LD: How I Added Rich Results Using Structured Data

Additionally, Google also offers the Rich Results Test which allows one to test if their markup is valid for Rich Results. This tool was quite useful while I was developing the update locally since it allows one to paste the code directly in.

Conclusion

For a small project, JSON-LD may or may not offer any benefits. In the case of my blog, it made sense to try and incorporate some into pages since it helps improve the way Google understands the content of the pages. Additionally, my blog is a tech blog, so taking the time to explore this technology offered an additional benefit of giving me something to write about. However, not every blog might benefit from incorporating it like mine.

Regardless, I think this is something other developers should consider exploring since it has a rich history and some practical applications in the web development space. For example, someone working on an eCommerce site may find rich results on Google lead to more customer engagement through organic search.

Moving forward, I want to try to find some other opportunities for improving the use of structured data on my website. One thing I would like to do is add markup for the images on blog posts. I could also explore markup for videos if I ever get around to trying my hand at making video content.

版本聲明 本文轉載於:https://dev.to/logarithmicspirals/boost-your-blogs-seo-with-json-ld-how-i-added-rich-results-using-structured-data-nob?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 在 C++ 中是否有必要檢查「this」是否為 Null?
    在 C++ 中是否有必要檢查「this」是否為 Null?
    關於檢查「this」是否為空的實用性在程式設計中,「this」指標指的是成員函數中的目前物件實例。它允許函數存取物件的資料和方法。然而,出現了一個問題:檢查「this」是否為空是否有意義? 讓我們考慮一個在類別中執行任務的方法:class MyClass { public: int myFu...
    程式設計 發佈於2024-11-07
  • 以下是一些適合您文章的基於問題的標題:

* 如何在 PHP 中將 dd/mm/yyyy 轉換為 yyyy-mm-dd:簡單指南
* PHP 日期格式轉換:dd/mm/yyyy 到 yyyy-mm-dd - 最佳方法
    以下是一些適合您文章的基於問題的標題: * 如何在 PHP 中將 dd/mm/yyyy 轉換為 yyyy-mm-dd:簡單指南 * PHP 日期格式轉換:dd/mm/yyyy 到 yyyy-mm-dd - 最佳方法
    PHP 日期格式轉換:dd/mm/yyyy 到yyyy-mm-dd在dd/mm/yyyy 和之間轉換日期格式yyyy-mm-dd 在PHP 可能具有挑戰性。 問題:使用 dd/mm/yyyy 格式的日期時會出現主要問題。由於斜線分隔符號 (/) 造成歧義,PHP 通常採用美國 m/d/y 格式,而不...
    程式設計 發佈於2024-11-07
  • 為什麼Go函數中修改指標有時不影響原值?
    為什麼Go函數中修改指標有時不影響原值?
    Go中指標的修改,理解差異在Go中,當指標傳遞給函數時,我們通常會修改值該指針所指向的。通常,這可以透過取消引用來實現,如下列程式碼所示:type Test struct { Value int } func main() { i := Test{2} p := &i...
    程式設計 發佈於2024-11-07
  • 週建構互動遊戲
    週建構互動遊戲
    第 2 周:构建互动游戏 第三课:游戏物理与运动 3.1 理解游戏物理 游戏物理涉及模拟现实世界的物理,使游戏更加真实和引人入胜。速度、加速度和重力等基本物理原理可以使游戏中的动作和交互感觉自然。 3.1.1 速度和加速度 速度是物体...
    程式設計 發佈於2024-11-07
  • 如何使用 BeautifulSoup 從 Python 中的 HTML 表中擷取資料?
    如何使用 BeautifulSoup 從 Python 中的 HTML 表中擷取資料?
    BeautifulSoup解析表在Python中,BeautifulSoup提供了強大的解析HTML文件的方法。當遇到這樣的場景,您需要從表格中檢索特定資料時,BeautifulSoup 就派上用場了。 要提取目標行項目表,請使用 soup.find(),在表中指定適當的屬性括號。在這種情況下,您需...
    程式設計 發佈於2024-11-07
  • 如何在react中使用PKCE實現oAuth以進行第三方集成
    如何在react中使用PKCE實現oAuth以進行第三方集成
    在為第三方整合實作oAuth時,我偶然發現了一些很長一段時間沒有更新的資訊。在這裡,我試著記錄我的經驗及其運作方式 注意:本文不會詳細討論oAuth及其運作方式。主要關注如何在 React 應用程式中配置和實現它們。如果您想了解 oAuth,請閱讀此處。提供清晰的資訊。 流程: 大...
    程式設計 發佈於2024-11-07
  • 為什麼我在 POST Jersey 請求中收到不支援的媒體類型錯誤?
    為什麼我在 POST Jersey 請求中收到不支援的媒體類型錯誤?
    POST Jersey 請求中不支援的媒體類型錯誤遇到HTTP 狀態代碼415 - 對Jersey 的POST 請求中不支持的媒體類型REST 服務,問題通常在於Jersey 發行版中缺少JSON/POJO 支援。要解決此錯誤,需要在專案中新增必要的 JAR 依賴項。 具體來說,需要以下依賴:jer...
    程式設計 發佈於2024-11-07
  • 針對 XSS 的常見防禦措施有哪些?
    針對 XSS 的常見防禦措施有哪些?
    針對 XSS 的常見防禦輸入和輸出清理是防止跨站腳本 (XSS) 攻擊的關鍵技術。本文探討了產業和個人網站廣泛採用的減輕這種威脅的方法。 1。 HTML 轉義:在將所有使用者輸入顯示為 HTML 程式碼之前徹底轉義它們。這涉及將“”、“&”和“等字元替換為其相應的HTML 實體(例如,“”、“&”、...
    程式設計 發佈於2024-11-07
  • Python垃圾收集器如何自動管理記憶體?
    Python垃圾收集器如何自動管理記憶體?
    Python 垃圾收集器文件Python 垃圾收集器是一個記憶體管理系統,可以自動釋放程式不再使用的記憶體。這有助於透過防止記憶體洩漏並確保程式不會耗盡記憶體來提高效能。 垃圾收集器的工作過程分為兩步:引用計數: 解釋器追蹤每個物件的引用數量。當引用計數達到零時,該物件被認為不可達,並添加到要刪除的...
    程式設計 發佈於2024-11-07
  • PHP 如何有效率地處理大整數?
    PHP 如何有效率地處理大整數?
    PHP 可以處理大整數嗎? PHP 可能沒有明確的「BigInteger」類,但它提供了幾種處理大整數的方法整數。 使用 BC 數學函數PHP 提供BC 數學函數,如用於整數算術的 bcadd() 和 bcsub()。然而,這種方法對於大量計算來說可能會很慢。 使用 GMP 擴展GMP(GNU 多精...
    程式設計 發佈於2024-11-07
  • 如何使用 Python 字串匹配驗證 IP 位址輸入?
    如何使用 Python 字串匹配驗證 IP 位址輸入?
    使用 Python 驗證 IP 位址輸入驗證使用者輸入的 IP 位址在各種應用中至關重要。本文將探討驗證以字串形式提供的 IP 位址合法性的最有效方法。 首選方法偏離解析,而是利用 Python 標準函式庫的套接字模組。透過利用 inet_aton(),我們可以確定輸入字串是否代表有效的 IP 位址...
    程式設計 發佈於2024-11-07
  • 那麼 Pull 請求如何再次發揮作用呢?螢幕顯示#3
    那麼 Pull 請求如何再次發揮作用呢?螢幕顯示#3
    在我之前的文章中,我談到了啟動一個基於開源 GenAI 的終端應用程式。本週的任務是為另一個用戶的專案貢獻一個新功能。由於我們必須與新人合作,所以我與 Lily 合作,她開發了一個應用程序,其代碼改進功能與我的類似,只是她的角色是老鼠! 有時間的話可以去看看她的專案老鼠助手。 她的程式碼是用 T...
    程式設計 發佈於2024-11-07
  • 為什麼 Go 中不能直接將 []string 轉換為 []interface{}?
    為什麼 Go 中不能直接將 []string 轉換為 []interface{}?
    為什麼將[]string 轉換為[]interface{} 會在Go 中引發編譯錯誤轉換字串切片([] string)考慮到它們共享切片特徵以及[]string 的每個元素都可以被視為一個接口,Go 中的接口切片([]interface{}) 似乎很簡單。然而,嘗試這種轉換時會出現編譯錯誤,讓程式設...
    程式設計 發佈於2024-11-07
  • 理解 Shadow DOM:封裝 Web 元件的關鍵
    理解 Shadow DOM:封裝 Web 元件的關鍵
    在現代 Web 開發中,創建可重複使用和可維護的元件至關重要。 Shadow DOM 是 Web 元件標準的一部分,在實現這一目標方面發揮著至關重要的作用。本文深入探討了 Shadow DOM 的概念、它的優點以及如何在您的專案中有效地使用它。 什麼是 Shadow DOM? Sh...
    程式設計 發佈於2024-11-07
  • 如何使用 Java 運行時解決輸出重定向問題?
    如何使用 Java 運行時解決輸出重定向問題?
    使用Runtime 的exec() 方法解決輸出重定向問題在Java 中,利用Runtime.getRuntime().exec() 運行指令可以擷取進程的輸出和錯誤流。但是,在需要輸出重定向的情況下,單獨使用此方法可能會無效。 問題:輸出未重定向當使用Runtime.getRuntime().ex...
    程式設計 發佈於2024-11-07

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3