Open utterances-bot opened 2 years ago
Great post! I followed along before the breaking changes and I'm now using this post to understand the svelteKit updates better(along with your other recent post on the topic) - its going well, thank you for this content!
Since the update, I noticed the transitions don't seem to have the same behavior. Example: You can see the footer flickering when switching between the 'About' and 'Contact' page on your demo (zoom out depending on screen size). Previously this sort of flickering didn't happen. I have a similar svelteKit app that I'm trying to manually convert and the animation jank is more noticeable.
Curious if you have any input, or if this is a svelteKit issue. Cheers!
@seepeekew The only browser I see the issue in is Safari, so I would guess it must be a Svelte issue that needs to be addressed in Webkit specifically. (Or…just a Safari issue. But there's probably a way to fix it in Svelte, I'd guess.)
Very useful contribution, Josh. Thanks for putting in the time & effort to update your original tutorial to account for the most recent breaking changes -- that has saved me a lot of time.
With dynamic routing (Approach 2), Svelte components imported into a post’s .md
file are not reactive.
e.g., I put the simple “Bindings / Text inputs” example in a Svelte component, imported it in a post .md
file, and used it as <TestComponent />
.
That component is displayed and its input element is enabled, but values entered in the input element do not update the reactive variable (wrapped in an <h1>
).
I assume this is owed to the load function in src/routes/blog/[posts]/+page.server.js
, the PostContent of which, post.default.render().html
, is returned to +page.svelte
as static html.
As the same Svelte component works as expected in .md
files structured as individual posts (Approach 1), I’m going with that bulkier solution for now.
But is there a way to modify the load
function to use dynamic routing without losing an imported Svelte component’s reactive behavior?
Does anyone notice an issue with the 'date' sorting function?
My api throws an error of 'Cannot read properties of undefined (reading 'date')', even if I can read all the dates in the api and as console.logs.
It's the only thing wrong now...
How would this work with SEO?
How do I get actual content of this?
export async function load({ params }) {
const post = await import(`../${params.slug}.md`);
const { title, date } = post.metadata;
const content = post.default;
console.log(content);
return {
title,
date,
content
};
}
This is an excellent post. Well-written; very clear. Thank you!
Hey Josh, it looks like Vite Process CSS handles sass/scss so no need for some of the steps written in the blog post about it.}
For others, you can read more about it here: https://vitejs.dev/guide/features.html#css-pre-processors
TLDR; just install the style preprocessor you want to use npm add -D sass
and vitePreprocess will take care of the rest.
(this was tested in v1.0.0 of svelte kit)
I compared the volume increase of some markdown files. My 23 files went from 41kB .md to 405kB .js files, a tenfold increase! Prolly unnecessary as .md can be expanded by the client, on the fly. Using adapter-static. As .html is not used, I predict there will be issues, adding ten yo legacy .html files, with very lax syntax.
prefetch
and prefetchRoutes
might be changed in latest version.
https://kit.svelte.dev/docs/migrating#pages-and-layouts-imports
Just wanted to add my thanks to the crowd. Awesome post. Extremely helpful and thanks for updating!
I initially went with option 2 for markdown content and then realized I had to import any components I used in the +page.svelte
as well as the mdsvex source itself. Just sucking everything into {@html ...}
felt wrong somehow, anyway (I used a server load so couldn't use svelte:component
).
Then I realized I like to keep source images in the same folder as my markdown anyway (and preprocess with vite-imagetools
). So option 1 made more sense anyway!
Thanks a lot for that post, It helped me get started with migrating a blog from Gatsby to SvelteKit!
One thing I found missing was ability to present excerpt of a post in blog listing, eg. by marking <!--more-->
in post content. I got used to it from way back with Wordpress and found a lib in Gatsby, but couldn't find anything similar in Svelte world.
So I made the lib :) : https://github.com/Zielak/mdsvex-excerpt
Honestly, I'm wondering if people still do excerpt on their blogs.
How do I get the actual content of the post displayed on the page with listed posts?
This is an awesome project! Thanks for making it available to all!
Just revisited the site after a while; still as helpful as ever! And thanks for keeping it updated.
I had to install prismic-themes for any styling of code blocks
Thanks again; this is my favourite Sveltekit tutorial and it has taught me a lot! :)
How can we escape angle brackets in markdown files? I've tried tried < > and other options but each gave me a parsing error like "Unexpected token". <
works but looks like code :)
Awesome!! :smiley:
Just a fabulous article Josh. This is exactly what I need for my project, so I'm going to go through it again with my actual site and content to build a prototype
This is AWESOME !!! Thank you Josh!
I really enjoyed the content! I learned a lot.
Does anyone have an example of how to apply pagination?
Absolutely loved the tutorial, I'm a newbie and I'm trying to understand the index.js used to import the MD files, I played around with the code and ended up with this:
var MDs = new Object;
for (const [path, importFunc] of Object.entries(import.meta.glob(`/src/routes/diaryof/*.md`))) { // The `...` is a template literal, how cool!
let data = await importFunc()
MDs[path.slice(11, -3)] = data.metadata
}
is this a valid alternative to the mapping function or do I have to study promises better?
I have a build problem after importing a static adapter.
@sveltejs/adapter-static: all routes must be fully prerenderable, but found the following routes that are dynamic:
Is your guide complete? Works that static adapter with approach 2?
@josh-collinsworth FYI With Contentlayer implementation and handling of markdown files is much easier.
Thank you so much for this article Josh, it helped me figure out some SvelteKit concepts, it's an amazing tool! Do you mind if I translate your article in French, with full credits and link here of course? The ressources outside the English environment are quite lacking to say the least.
There's something I couldn't wrap my head around using the API endpoint and filtering. I wanted to create a single API endpoint listing all the posts regardless of where they are by modifying const allPostFiles = import.meta.glob('/src/routes/blog/*.md')
to const allPostFiles = import.meta.glob('/src/routes/*/*.md')
and from then using some kind of filtering to display them in their correct routes according to the categories, but I can't figure out how or where I should do that. Can you point me in the right direction?
EDIT: I figured it out, I was trying to apply filter() before receiving the response.json().
@Maratzz Glad you were able to figure it out. :) And yes, you're welcome to translate content with attribution. Thanks!
Hi Josh, thank you so much for this tutorial. I am trying to use an alias for dynamic routing:
const post = await import(`$posts/${params.slug}.md`)
where I configured $posts
in svelte.config.js as $posts: './src/posts'
. This avoids a relative path like ./../../../posts
. However, this doesn't seem to be working. Can you help me out here?
Hi Josh, another question. I tried adding the scss :where(h2, h3, h4, h5, h6)
code block to a <style lang="scss">
tag inside +page.svelte in the /blog/[slug] folder. Can't we do this? Does it have to be inside $lib/styles/style.scss?
This is Incredible, thank you very much
Is super content. Thanks
Hi. Can you tell me how to make articles that have the draft: true
parameter added to the frontmetter do not appear at all. I added this to the api/posts/server.js
and articles are not displayed in the blog, but the article itself is available by url
import { getMarkdownPosts } from '$lib/utils/getPosts'
import { json } from '@sveltejs/kit'
export const GET = async () => {
const allPosts = await getMarkdownPosts()
const notDraftPosts = allPosts.filter(post => post.meta.draft === false)
const sortedPosts = notDraftPosts.sort((a, b) => {
return new Date(b.meta.date) - new Date(a.meta.date)
})
return json(sortedPosts)
}
This is a great post. Thank you very much! It is very helpful.
Thank you so much, this is so useful ! But, I just can't understand how "resolver" works ; "resolve" exists in the doc but not "resolver". Could you explain that to a brave neophyte like me, please ?
Sorry if this is a very novice question (it's been a while since I've used Node). You save all of npm packages to devDependencies (as opposed to just dependencies). Is this because SvelteKit generates what should run in production for you? Reason I ask is that I always want to understand the why of everything I'm doing.
Thanks for a great and detail guide! I'm using it to get my blog on to SvelteKit (and learn it in the process). I really appreciate that you explain why and how you are doing things, making it possible for me to use that understanding to solve things the way I want and not blindly follow the tutorial.
@leokolt You can see how I handle hiding post drafts here: josh-collinsworth/joco-sveltekit/src/lib/assets/js/utils/fetchPosts.ts
@Mellifico "Resolver" is just my own word. When you import a markdown file, you get an object where the key is the path to the file, and the value is a function that generates its content, something like this:
{
'/blog/my-post.md': asyncFunctionThatGetsThisPostsContent()
}
I just call that function "resolver" because you have to assign it a name when looping over the entries. You could call it whatever you want. It's just a function that runs asynchronously and (eventually) returns all of the details of the post for you.
@torb-no My understanding is: devDependencies is for things that are required to either help with development (like eslint, prettier, a dev server), or things that help with building and compilation. These are dependencies that, in other words, help the site get built, but not that actually run on the production site.
Sass is a good example; Sass does not run on the live website, since by the time you get the code to production, all the Sass code has been compiled away to pure CSS. So setting something as a devDependency signals to the build step that the package is not needed in production.
Such a good article!
I'm trying to follow through the tutorial and I've run into an issue: after I install mdsvex
and modify svelte.config.js
, I created a +page.md file as instructed but now it fails with this error:
Files prefixed with + are reserved (saw src/routes/uses/+pages.md)
I'm using vitePreprocess
(seems to come default that way now) but I switched to sveltePreprocess
to check and it didn't change anything. I've stopped the server (it restarts automatically when it sees the config change, but just to be sure) and started it again but that doesn't fix it.
Assuming you're starting from scratch, #1 seems useful if you want to colocate markdown files with images. But it can be annoying since you have to name the path and the file title. In #2 you'd have to name the .md file and the title which might as well be the same as naming the folder and title. So you end up naming two things either way.
btw: think
If you followed approach #1 above and have every post inside its own individual folder, you'll need to change the import path to end /blog/*/.md, to go one level deeper.
should be: /blog/**/*.md
I Loved it! Your tutorial really helped with my blog, thank you!
Let's learn SvelteKit by building a static Markdown blog from scratch - Josh Collinsworth blog
Learn the fundamentals of SvelteKit by building a statically generated blog from scratch, with Markdown support, Sass, an API, and an RSS feed.
https://joshcollinsworth.com/blog/build-static-sveltekit-markdown-blog