欢迎浮层(深色主题)的实际渲染效果

Astro 是一个主打速度和内容站点的静态站点生成器。给博客加一个欢迎界面,能让访客第一眼就感受到你的风格,也能放一句问候、一条公告或一组快捷入口。本文用纯前端的方式,教你在 Astro 博客里加一个"首次访问才弹出"的欢迎浮层。

思路

欢迎界面本质上是一个覆盖在页面上的弹窗(overlay)。关键点是:

  • localStorage 记录"是否已经展示过",避免每次刷新都弹。
  • 用 Astro 的 <script> 标签写客户端逻辑(Astro 会自动做打包和类型检查)。
  • 样式和遮罩都写在组件里,不依赖任何第三方库。

第一步:创建 Welcome 组件

src/components/ 下新建 Welcome.astro

---
// Welcome.astro
---
<div id="welcome-mask" class="welcome-mask" hidden>
  <div class="welcome-card">
    <h2>欢迎来到我的博客</h2>
    <p>这里记录技术笔记与生活碎片,慢慢看,不着急。</p>
    <button id="welcome-close">开始阅读</button>
  </div>
</div>

<style>
  .welcome-mask {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 9999;
  }
  .welcome-card {
    background: #171717;
    color: #e4e4e4;
    padding: 2rem;
    border-radius: 8px;
    max-width: 420px;
    text-align: center;
    border: 1px solid #333;
  }
  .welcome-card button {
    margin-top: 1rem;
    padding: 0.5rem 1.5rem;
    background: #e4e4e4;
    color: #171717;
    border: none;
    border-radius: 4px;
    cursor: pointer;
  }
</style>

<script>
  const KEY = 'welcomed';
  const mask = document.getElementById('welcome-mask') as HTMLElement | null;
  const btn = document.getElementById('welcome-close') as HTMLElement | null;

  if (mask && !localStorage.getItem(KEY)) {
    mask.hidden = false;
  }
  btn?.addEventListener('click', () => {
    mask && (mask.hidden = true);
    localStorage.setItem(KEY, '1');
  });
</script>

欢迎浮层(浅色主题)的实际渲染效果

第二步:在全局布局里引入

打开你的全局布局(通常是 src/layouts/BaseLayout.astro),在 <body> 末尾引入组件:

---
import Welcome from '../components/Welcome.astro';
---
<body>
  <slot />
  <Welcome />
</body>

这样全站任意页面加载时都会尝试展示欢迎浮层。

进阶:每天只弹一次 / 定时公告

如果希望每天都弹(比如做每日一言),把判断改成按日期存:

const today = new Date().toISOString().slice(0, 10);
if (localStorage.getItem('welcomed') !== today) {
  mask.hidden = false;
}
btn?.addEventListener('click', () => {
  mask.hidden = true;
  localStorage.setItem('welcomed', today);
});

如果想做全站公告而不是个人欢迎,把逻辑放到服务端更稳妥:在布局里读一个配置或环境变量,决定是否展示,这样你能随时开关而无需改代码。

服务端渲染版本(SSR)

如果你的 Astro 开了 SSR(output: 'server''hybrid'),也可以在页面里直接用 Astro 的 Astro.cookies 来判断:

---
const seen = Astro.cookies.get('welcomed')?.value;
---
{!seen && (
  <div class="welcome-mask">…欢迎内容…</div>
)}

客户端再补一段写 cookie 的逻辑即可。SSR 的好处是逻辑在服务端完成,不会被用户清掉 localStorage 就反复弹。

小结

  • 纯静态站:用 localStorage + Astro <script> 客户端控制。
  • 想要可控:用 SSR + cookie,在后台随时开关。
  • 样式、文案都在这一个组件里,改起来很方便。

加上欢迎界面后,你的 Astro 博客就多了一点人情味。