Good afternoon. I have a website on Svelt based on markdown files. I need to make sure that posts are not published, excluded from the list of posts, if there is published: false
in the frontmetter of these posts
Let’s start with the fact that I have a utility function that pulls these posts from md files
/*lib/utils/getPosts.js*/
// @ts-nocheck
export const getMarkdownPosts = async () => {
const allPostFiles =
import.meta.glob('/src/content/posts/*.md')
const iterablePostFiles = Object.entries(allPostFiles)
const allPosts = await Promise.all(
iterablePostFiles.map(async ([path, resolver]) => {
const { metadata } = await resolver()
//const postPath = path.slice(11, -3)
const postPath = path.split('/').at(-1)?.replace('.md', '')
return {
meta: metadata,
path: postPath,
}
})
)
return allPosts
}
Then I have a server function in api/posts/+server.js
/*api/posts/+server.js*/
import { getMarkdownPosts } from '$lib/utils/getPosts'
import { json } from '@sveltejs/kit'
export const GET = async () => {
const allPosts = await getMarkdownPosts()
const sortedPosts = allPosts.sort((a, b) => {
return new Date(b.meta.date) - new Date(a.meta.date)
})
return json(sortedPosts)
}
Here is the load function that serves to build the article page.
/*blog/[slug]/+page.js*/
export async function load({ params }){
const post = await import(`../../../content/posts/${params.slug}.md`)
const { title, date, categories, draft } = post.metadata
const content = post.default
return {
content,
title,
date,
categories
}
}
I changed my server function (code below) and now it filters posts perfectly, without showing posts in the listing of posts where published: false
is indicated in the frontmetter.
/*api/posts/+server.js*/
import { getMarkdownPosts } from '$lib/utils/getPosts'
import { json } from '@sveltejs/kit'
export const GET = async () => {
const allPosts = await getMarkdownPosts()
const sortedPosts = allPosts.sort((a, b) => {
return new Date(b.meta.date) - new Date(a.meta.date)
}).filter(post => post.meta.published === true)
return json(sortedPosts)
}
But an article with the specified published: false will still be available via a direct link, like http://localhost:5173/blog/first-post . And you need this article not to be on the site at all, that is, a 404 error or something like that would be displayed. Can I take this?
2
Answers
In fact, as I thought, everything is much simpler. Since it is quite simple to remove posts from
published: false
from the general list of articles, it was just necessary to apply.filter(post => post.meta.published === true)
Remove the posts altogether and output 404 instead, you can simply add such code to the load function in the file
/*blog/[slug]/+page.js*/
So the whole code of this file looks like this:
Check out SvelteKit param matching!
The steps to implement should be something like this:
blog/[slug=published]/+page.js
/src/params/
, create a function that checks for a match:blog/[slug]/+error.svelte
(notice that the path isslug
, notslug=published
)Disclaimers:
+page.md
, and you can use JS imports to get functions and Svelte components into your markdown files.