Skip to content

文章隐藏 / 加密

危险

隐藏和加密功能防君子不防小人,请勿用在隐私文章上

隐藏

在文章的 frontmatter 中设置 display: none 即可将文章隐藏,隐藏后文章将不再出现在列表中

此外建议同时设置 head 避免搜索引擎收录

md
---
display: none
head:
  - - meta
    - name: robots
      content: noindex, nofollow
---

通过 usePosts 可以获取到隐藏的文章列表 hiddenPosts,最后在 sitemap 中将这些文章排除

.vitepress/config.ts
ts
const { hiddenPosts } = await usePosts();

export default defineConfig<ThemeConfig>({
  sitemap: {
    hostname: 'https://example.com',
    transformItems: (items) => {
      // 排除不需要的路径
      items = items.filter((item) => !hiddenPosts.some((post) => item.url.includes(post.permalink.slice(1))));
      return items;
    }
  }
});

加密

隐藏文章后,只是不出现在列表中,如果知道文章的 URL 仍然可以访问,此时可以配合加密功能使用。

当然,你也可以单独使用加密功能。

导出两个变量用于配置密码,并在 onBeforeRouteChange拦截加密文章的路由

  • defaultPassword 为默认密码
  • passwordConfig 为文章的密码配置
    • key 为文章的 ID(永久链接的后半部分)
    • value 为对应文章的密码,留空则使用默认密码。
.vitepress/theme/index.ts
ts
export const defaultPassword = 'vitepress-theme-minimalism';

export const passwordConfig: Record<string, string> = {
  post1: '123',
  post2: '456',
  post3: ''
};

export default {
  enhanceApp({ router }: { router: Router }) {
    if (inBrowser) {
      const themeBefore = router.onBeforeRouteChange;
      const themeAfter = router.onAfterRouteChange;

      router.onBeforeRouteChange = (to) => {
        themeBefore?.(to);
        if (to.includes('password')) return;

        // 查找匹配的文章 ID
        const postId = Object.keys(passwordConfig).find((id) => to.includes(id));
        if (!postId) return; // 如果没有匹配的文章,不需要密码

        // 从 localStorage 中获取所有文章的密码对象
        const passwordsObj = JSON.parse(localStorage.getItem('post_passwords') || '{}');
        const configuredPassword = passwordConfig[postId];
        // 如果配置的密码为空,使用默认密码
        const correctPassword = configuredPassword || defaultPassword;

        // 检查该文章的密码是否已验证且正确
        if (passwordsObj[postId] === correctPassword) return;

        router.go(`/password?redirect=${to}`);

        return false;
      };
    }
  }
};

最后在根目录创建一个 password.md 填入以下内容,该文件为密码输入的页面

password.md
md
---
title: 输入访问密码
layout: page
---

<script setup>
import { passwordConfig, defaultPassword } from '/.vitepress/theme/index.ts';
</script>

<Password :passwordConfig="passwordConfig" :defaultPassword="defaultPassword" />