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

SvelteKit静态博客实现按客户端当前日期过滤文章

kit: {
    adapter: adapter(),
}

}

#### +layout.ts
```typescript
export const prerender = true;

BlogPosts.svelte

<script>
    export let posts: BlogPost[];
</script>

<section>
    <ul class="posts">
        {#each posts as post}
            <li class="post">
                <a href={post.slug} class="title">{post.title}</a>
                ...
            </li>
        {/each}
    </ul>
</section>

+page.svelte

<script>
    export let data;
</script>

<BlogPostList posts={data.postsAsOfToday} />

+page.ts

export async function load({ fetch }) {
    // 接口返回仓库中所有markdown文件对应的博客文章
    const response = await fetch(base + '/api/blog');
    const posts: BlogPost[] = await response.json();
    const dateToday = new Date();
    const postsAsOfToday = posts.filter((post) => new Date(post.date) <= dateToday);
    return { postsAsOfToday };
}

尝试过但无效的写法

<!-- BlogPosts.svelte -->
{#each posts as post}
    {#if new Date(post.date) <= new Date()}
        ...
    {/if}
{/each}

解决方案

完全可以实现客户端运行时过滤,同时保持静态博客的属性。核心逻辑是:把所有文章数据打包进静态文件,让浏览器加载页面时,用客户端的当前日期实时过滤内容,而非在构建阶段就剔除未到发布日期的文章。

1. 修改+page.ts,返回全部文章

移除构建阶段的过滤逻辑,直接返回所有文章,确保所有内容都被预渲染到静态资源中:

// +page.ts
export async function load({ fetch }) {
    const response = await fetch('/api/blog');
    const posts: BlogPost[] = await response.json();
    // 不再在构建时过滤,返回所有文章
    return { allPosts: posts };
}

2. 调整组件逻辑,在客户端实时过滤

先修改+page.svelte,把全部文章传给组件:

<!-- +page.svelte -->
<script>
    export let data;
</script>

<BlogPosts posts={data.allPosts} />

再修改BlogPosts.svelte,用Svelte的响应式变量触发客户端实时判断:

<!-- BlogPosts.svelte -->
<script>
    export let posts: BlogPost[];
    // 响应式变量,每次页面加载/刷新时获取客户端当前日期
    $: currentDate = new Date();
</script>

<section>
    <ul class="posts">
        {#each posts as post}
            {#if new Date(post.date) <= currentDate}
                <li class="post">
                    <a href={post.slug} class="title">{post.title}</a>
                    <!-- 其他文章内容 -->
                </li>
            {/if}
        {/each}
    </ul>
</section>

3. 保留静态预渲染配置

保持svelte.config.js和+layout.ts的原有配置不变,确保博客仍为静态预渲染模式:

// svelte.config.js
import adapter from '@sveltejs/adapter-static';

const config = {
    // 其他原有配置
    kit: {
        adapter: adapter(),
    }
}

export default config;
// +layout.ts
export const prerender = true;

为什么之前的尝试无效?

之前在BlogPosts.svelte中直接加判断没生效,是因为Svelte预渲染时会在构建阶段执行模板逻辑,生成静态HTML时就把未到发布日期的文章过滤掉了。现在通过打包所有文章数据,并使用响应式变量$: currentDate = new Date(),确保每次页面加载时都会用浏览器的当前日期重新过滤内容。

额外提示

  • 确保文章的date字段是合法格式(如YYYY-MM-DD),否则new Date(post.date)无法正确解析。
  • 如果担心未发布文章的内容被用户通过查看源代码看到,可以把文章正文放在单独的路由中,仅当用户点击已发布的文章链接时才加载对应内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 17:23:15