Open brc-dd opened 1 year ago
When #631 is done, an example with translations should be added (to this list) as well!
Any updates to SEO Improvement? I did not find any examples of meta tags / JSON-LD.
@ryan4yin Yeah now there are multiple hooks that can add head tags based on the page. So you can have site level head tags + page level tags (say for generating og images, overriding description, stuff like that). But there aren't much examples right now. Any particular thing you're looking for?
docs: https://vitepress.dev/reference/site-config#head, https://vitepress.dev/reference/site-config#transformpagedata, https://vitepress.dev/reference/site-config#transformhead
@brc-dd I want to insert a JSON-LD to the head of every page.
For example, Home Page should contain a head
like this:
<html>
<head>
<script type="application/ld+json">
{
"@context":"http://schema.org",
"@type":"WebSite",
"url":"https:\/\/nixos-and-flakes.thiscute.world\/zh\/",
"inLanguage":"zh-CN",
"author":{"@type":"Person","name":"ryan4yin"},
"description":"NixOS & Flakes Book",
"name":"NixOS & Flakes Book"
}
</script>
...
And every other page should have a head
like this(with its own url):
<html>
<head>
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "BlogPosting",
headline: "NixOS \u0026 Nix Flakes - A Guide for Beginners",
inLanguage: "en",
mainEntityOfPage: {
"@type": "WebPage",
"@id": "https:\/\/thiscute.world\/en\/posts\/nixos-and-flake-basics\/",
}
],
keywords: "NixOS, Nix, Flakes, Linux, DevOps, Tutorial",
url: "https:\/\/thiscute.world\/en\/posts\/nixos-and-flake-basics\/",
}
</script>
...
@ryan4yin Do something like this:
import { defineConfig } from 'vitepress';
export default defineConfig({
transformPageData(pageData) {
return {
frontmatter: {
...pageData.frontmatter,
head: [
[
'script',
{ type: 'application/ld+json' },
pageData.relativePath === 'index.md'
? `
{
"@context":"http://schema.org",
"@type":"WebSite",
"url":"https:\/\/nixos-and-flakes.thiscute.world\/zh\/",
"inLanguage":"zh-CN",
"author":{
"@type":"Person",
"name":"ryan4yin"
},
"description":"NixOS & Flakes Book",
"name":"NixOS & Flakes Book"
}`
: `
{
"@context":"http://schema.org",
"@type":"BlogPosting",
"headline":"NixOS \u0026 Nix Flakes - A Guide for Beginners",
"inLanguage":"en",
"mainEntityOfPage":{
"@type":"WebPage",
"@id":"https:\/\/thiscute.world\/en\/posts\/nixos-and-flake-basics\/"
},
"keywords":"NixOS, Nix, Flakes, Linux, DevOps, Tutorial",
"url":"https:\/\/thiscute.world\/en\/posts\/${pageData.relativePath
.replace(/\.md$/, '')
.replace(/\/index$/, '')}\/"
}`,
],
],
},
};
},
});
@brc-dd Thanks a lot, it works, the config I use:
function getJSONLD(pageData: PageData) {
if (pageData.relativePath === "index.md") {
return `{
"@context":"http://schema.org",
"@type":"WebSite",
"url":"https:\/\/nixos-and-flakes.thiscute.world\/",
"inLanguage":"en",
"description":"An unofficial and opinionated book for beginners",
"name":"${pageData.title}"
}`;
} else if (pageData.relativePath === "zh/index.md") {
return `{
"@context":"http://schema.org",
"@type":"WebSite",
"url":"https:\/\/nixos-and-flakes.thiscute.world\/zh\/",
"inLanguage":"zh-CN",
"description":"一份非官方的新手指南",
"name":"${pageData.title}"
}`;
} else {
let lang = pageData.relativePath.startsWith("zh/") ? "zh-CN" : "en";
let url = `https:\/\/nixos-and-flakes.thiscute.world\/${pageData.relativePath
.replace(/\.md$/, ".html")
.replace(/\/index\.html$/, "/")}`;
return `{
"@context":"http://schema.org",
"@type":"TechArticle",
"headline":"NixOS & Flakes Book",
"inLanguage":"${lang}",
"mainEntityOfPage":{
"@type":"WebPage",
"@id":"${url}"
},
"keywords":"NixOS, Nix, Flakes, Linux, Tutorial",
"url":"${url}"
}`;
}
}
// https://vitepress.dev/reference/site-config
export default defineConfig({
// SEO meta tags / JSON-LD
transformPageData(pageData) {
return {
frontmatter: {
...pageData.frontmatter,
head: [
["script", { type: "application/ld+json" }, getJSONLD(pageData)],
],
},
};
},
......
});
@brc-dd
import { defineConfig } from 'vitepress'; export default defineConfig({ transformPageData(pageData) { return { frontmatter: { ...pageData.frontmatter, head: [ [ 'script', { type: 'application/ld+json' }, pageData.relativePath === 'index.md'
When I using Dynamic Routes. To uniformly manage and generate pages with a consistent structure, which involves changing the header
#2516, the suggestion is also to use .vitepress/config.js
to use transformPageData
I was wondering if transformPageData
would be in Dynamic Routes configure [pkg].paths.js
. Avoid me adding too much judgment in .vitepress/config.js
, and managing it in only one place.
.
└─ packages
├─ [pkg].md # route template
└─ [pkg].paths.js # route paths loader
// packages/[pkg].paths.js
export default {
paths() {
return [
{ params: { pkg: 'foo' }},
{ params: { pkg: 'bar' }}
]
},
transformPageData(pageData) {
// ...
}
}
Yeah I think we can support that. I'll take a look.
Is there any example of changing the following meta tags per page basis ? Meta for OG Meta for Twitter Canonical URL
keen to understand best practices for versioning or if there is a way to do it in the same site like docusaurus
Versioning isn't supported. There might be some hacky workarounds, but it'd need some changes at VitePress level.
@joel666 Yeah, you can use transformPageData or transformHead functions to add those entries on page by page basis.
@ryan4yin I tried to come up with a component that allows structured data in markdown itself, not sure if that helps anyone or if this is even the right approach:
SchemaOrg.vue component:
<script lang="ts">
import {h} from "vue";
export default {
setup(props, {slots}) {
if (!slots?.default) {
return () => null;
}
return () =>
h("script", {
innerHTML: slots.default?.().map(el => el.children).join(''),
type: "application/ld+json",
});
},
};
</script>
usage in markdown:
<SchemaOrg>{
"@context": "https://schema.org",
"@type": "..."
}
</SchemaOrg>
at least for me it renders correctly and is also written correctly to the static build variant.
For the versioning example; maybe could build off this? https://github.com/vuejs/vitepress/issues/109#issuecomment-1869740170
As mentioned in #253, we probably should add a community examples page. Here are the things that we can add:
Markdown Extensions
SEO Improvement
Image Extensions
Complex Use-Cases
Integration with other libraries:
I created this list based on popular VuePress plugins and VitePress issues. Having such a page before v1 will significantly ease up migration. If you think the list is missing something common then please comment.
Some of these can be officially supported too, especially the markdown extensions.