vuejs / vitepress

Vite & Vue powered static site generator.
https://vitepress.dev
MIT License
11.48k stars 1.86k forks source link

Add examples #883

Open brc-dd opened 1 year ago

brc-dd commented 1 year ago

As mentioned in #253, we probably should add a community examples page. Here are the things that we can add:

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.

ye-ole-dev commented 1 year ago

When #631 is done, an example with translations should be added (to this list) as well!

jd-solanki commented 1 year ago

I would like to submit my lib's docs site if VitePress is going to add section for "Projects using VitePress" like VuePress

Thanks

ryan4yin commented 10 months ago

Any updates to SEO Improvement? I did not find any examples of meta tags / JSON-LD.

brc-dd commented 10 months ago

@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

ryan4yin commented 10 months ago

@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>
  ...

related: https://github.com/vuejs/vitepress/issues/538

brc-dd commented 10 months ago

@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$/, '')}\/"
}`,
          ],
        ],
      },
    };
  },
});
ryan4yin commented 10 months ago

@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)],
        ],
      },
    };
  },

  ......
});
Zhengqbbb commented 10 months ago

@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) {
    // ...
  }
}
brc-dd commented 10 months ago

Yeah I think we can support that. I'll take a look.

joel666 commented 9 months ago

Is there any example of changing the following meta tags per page basis ? Meta for OG Meta for Twitter Canonical URL

jcstein commented 8 months ago

keen to understand best practices for versioning or if there is a way to do it in the same site like docusaurus

brc-dd commented 8 months ago

Versioning isn't supported. There might be some hacky workarounds, but it'd need some changes at VitePress level.

brc-dd commented 8 months ago

@joel666 Yeah, you can use transformPageData or transformHead functions to add those entries on page by page basis.

adrianrudnik commented 5 months ago

@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.

IMB11 commented 4 months ago

For the versioning example; maybe could build off this? https://github.com/vuejs/vitepress/issues/109#issuecomment-1869740170