You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为blogdown网站添加类似bookdown的搜索栏?

绝对可以给你的blogdown笔记站加上类似bookdown的搜索栏!用lunr.js实现静态搜索其实没你想的那么复杂,我把具体步骤拆解开,跟着做就能搞定:

1. 生成搜索所需的页面数据源

首先得让lunr.js能获取到你所有笔记的标题、标签和内容,我们需要生成一个JSON格式的数据源文件。在blogdown的layouts/目录下新建一个search.json模板文件,粘贴以下内容:

[
  {{ range $index, $page := .Site.Pages }}
    {{ if eq $page.Type "page" }} // 这里可以根据你的需求过滤页面,比如只收录笔记类型页面
    {
      "url": "{{ $page.Permalink }}",
      "title": "{{ $page.Title }}",
      "tags": [{{ range $tagIndex, $tag := $page.Tags }}"{{ $tag.Name }}"{{ if ne $tagIndex (sub (len $page.Tags) 1) }}, {{ end }}"],
      "content": "{{ $page.Content | plainify | safeJS }}"
    }{{ if ne $index (sub (len .Site.Pages) 1) }}, {{ end }}
    {{ end }}
  {{ end }}
]

站点构建时,这个模板会自动在根目录生成search.json,里面包含所有符合条件的页面信息。

2. 引入lunr.js和自定义搜索脚本

找个合适的地方(比如站点的footer.html或者header.html模板片段),添加lunr.js的CDN引用和搜索逻辑脚本:

<!-- 引入lunr.js库 -->
<script src="https://cdn.jsdelivr.net/npm/lunr@2.3.9/lunr.min.js"></script>

<!-- 自定义搜索功能脚本 -->
<script>
// 加载搜索数据源
fetch('/search.json')
  .then(response => response.json())
  .then(data => {
    // 初始化lunr搜索索引
    const idx = lunr(function () {
      this.ref('url');
      this.field('title', { boost: 10 }); // 标题权重设高,搜索时优先匹配标题
      this.field('tags', { boost: 5 });   // 标签权重次之
      this.field('content');

      data.forEach(doc => {
        this.add(doc);
      });
    });

    // 获取搜索框和结果容器元素
    const searchInput = document.getElementById('search-input');
    const searchResults = document.getElementById('search-results');

    // 监听搜索输入事件
    searchInput.addEventListener('input', function () {
      const query = this.value.trim();
      if (!query) {
        searchResults.innerHTML = '';
        return;
      }

      // 执行搜索并渲染结果
      const results = idx.search(query);
      let resultHtml = '';
      results.forEach(result => {
        const doc = data.find(item => item.url === result.ref);
        resultHtml += `
          <div class="search-result-item">
            <h3><a href="${doc.url}">${doc.title}</a></h3>
            <p class="search-tags">${doc.tags.join(', ')}</p>
            <p class="search-excerpt">${doc.content.substring(0, 150)}...</p>
          </div>
        `;
      });
      searchResults.innerHTML = resultHtml;
    });
  });
</script>
3. 添加搜索界面的HTML结构

在你想放置搜索栏的位置(比如导航栏顶部、页面侧边栏)插入搜索框和结果容器的HTML:

<div class="search-box-wrapper">
  <input type="text" id="search-input" placeholder="搜索你的笔记...">
  <div id="search-results" class="search-results-list"></div>
</div>
4. 美化搜索样式(可选)

给搜索界面加一点基础CSS,让它看起来更舒服,比如把这段代码放在你的站点样式文件里:

.search-box-wrapper {
  position: relative;
  max-width: 450px;
  margin: 1rem auto;
}
#search-input {
  width: 100%;
  padding: 0.75rem 1rem;
  border: 1px solid #e0e0e0;
  border-radius: 4px;
  font-size: 1rem;
}
.search-results-list {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  border: 1px solid #e0e0e0;
  border-top: none;
  border-radius: 0 0 4px 4px;
  background: white;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  z-index: 100;
}
.search-result-item {
  padding: 1rem;
  border-bottom: 1px solid #f0f0f0;
}
.search-result-item:last-child {
  border-bottom: none;
}
.search-result-item h3 {
  margin: 0 0 0.5rem;
  font-size: 1.1rem;
}
.search-tags {
  margin: 0 0 0.5rem;
  font-size: 0.85rem;
  color: #666;
}
.search-excerpt {
  margin: 0;
  font-size: 0.9rem;
  color: #333;
}
5. 测试与调整

完成上面的步骤后,运行blogdown::build_site()构建站点,然后本地预览测试。如果有些页面没被收录,可以修改search.json里的过滤条件;如果搜索结果的优先级不符合预期,调整lunr初始化时的boost参数即可。

内容的提问来源于stack exchange,提问作者TJ Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:10:04