Releases: wesbitty/wesjet
✨Wesjet v0.0.30
💥 Initial Stable Release
Wesjet SDK Validates & Transforms Content into type-safe JSON data to ease importing content into your application's pages easily.
Features
- Fast and incremental builds
- Live reload on content changes
- Powerful schema DSL to design your content model (validates your content and compiles types)
- Compile TypeScript types based on your content model automatically (e.g. frontmatter or CMS schema)
Supported Environments
Supported Content Sources
- Local content (Markdown, MDX, JSON, YAML)
Local Installation
Npm downloads wesjet into your project’s folder, wesjet files are installed “locally” to your project.
npm install wesjet —save-dev
You may notice a .wesjet folder in your projects. This is the folder that holds generated content. As you add more content to your project, this folder will get heavier.
Global Installation
Think of a global installation as if you’re downloading wesjet to your computer so you can use it outside of your current project. You can globally install wesjet by using the -g flag when installing.
npm install wesjet -g
Getting Started
Create a new Next.js project
npx create-next-app@latest
Add wesjet into the next build and next dev processes. To archive this, you'll need to wrap Next.js configuration using the wesjetConfig instead of nextConfig method.
Goto next.config.js in the root of your project, and add the following content.
const { wesjetConfig } = require('wesjet/next')
export default wesjetConfig({
// Add Next.js Config Option that’s suitable for your project.
})
Then add the following lines to your tsconfig.json or jsconfig.json file:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"wesjet/static": ["./.wesjet/static"]
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
},
"include": [“.wesjet/static”, "next-env.d.ts", "**/*.tsx"]
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
Wesjet generates files in the .wesjet/static directory. This tells JavaScript (or TypeScript) to create an alias of wesjet/static to the generated files directory.
Finally, add the .wesjet directory into your .gitignore file to ensure each build of your app will have the latest generated data and you do not run into issues with git.
Add Post Schema
By default, you’re using .md file extension
- Create a directory with the name [Post] in the root of your project.
Add your blog post with a .md or .mdx file extension
- Post directory structure should look like:
[Post]/
├── latest-gist.md
├── post-02.md
└── post-03.md
- Add Post Content
Create a few markdown files in [Post] directory and add some content to those files.
Here's an example of what a post file at [Post]/latest-gist.md might look like:
---
title: Latest Gist
date: 2023-04-19
---
Ullamco et nostrud magna commodo nostrud occaecat quis pariatur id ipsum. Ipsum
consequat enim id excepteur consequat nostrud esse esse fugiat dolore.
Reprehenderit occaecat exercitation non cupidatat in eiusmod laborum ex eu
fugiat aute culpa pariatur. Irure elit proident consequat veniam minim ipsum ex
pariatur.
Mollit nisi cillum exercitation minim officia velit laborum non Lorem
adipisicing dolore. Labore commodo consectetur commodo velit adipisicing irure
dolore dolor reprehenderit aliquip. Reprehenderit cillum mollit eiusmod
excepteur elit ipsum aute pariatur in. Cupidatat ex culpa velit culpa ad non
labore exercitation irure laborum.
- Create a wesjet.config.js file at the root of your project.
// wesjet.config.js
import { defineDocumentType, makeSource } from 'wesjet/preset'
export const Post = defineDocumentType(() => ({
name: 'Post',
filePathPattern: `**/*.md`,
fields: {
title: {
type: 'string',
description: 'The title of the post',
required: true,
},
date: {
type: 'date',
description: 'The date of the post',
required: true,
},
},
computedFields: {
url: {
type: 'string',
resolve: (post) => `/blog/${post._raw.flattenedPath}`,
},
},
}))
export default makeSource({
contentDirPath: '[Post]',
documentTypes: [Post],
})
Date Formatting Helper
Before we get into the pages, add a library to help us with formatting the date.
npm install date-fns
Add Post Page directory
- Create a blog.js directory at
pages/blog.jswith a listing of all the posts and links to the individual post pages.
// pages/blog.js
import Head from 'next/head'
import Link from 'next/link'
import { compareDesc, format, parseISO } from 'date-fns'
import { allPosts } from 'wesjet/static'
export async function getStaticProps() {
const posts = allPosts.sort((a, b) => {
return compareDesc(new Date(a.date), new Date(b.date))
})
return { props: { posts } }
}
function PostCard(post) {
return (
<div className="mb-6">
<time dateTime={post.date} className="block text-sm text-slate-600">
{format(parseISO(post.date), 'LLLL d, yyyy')}
</time>
<h2 className="text-lg">
<Link href={post.url}>
<a className="text-blue-700 hover:text-blue-900">{post.title}</a>
</Link>
</h2>
</div>
)
}
export default function Blog({ posts }) {
return (
<div className="mx-auto max-w-2xl py-16 text-center">
<Head>
<title>Blog - Wesjet</title>
</Head>
<h1 className="mb-8 text-3xl font-bold">Latest Gist</h1>
{posts.map((post, idx) => (
<PostCard key={idx} {...post} />
))}
</div>
)
}
Add Post Layout
Notice that if you click on individual posts, you get a 404 error. That's because we haven't created the pages for these posts. Let's do that!
- Create the page at
pages/posts/[slug].jsand add the following code.
// pages/posts/[slug].js
import Head from 'next/head'
import Link from 'next/link'
import { format, parseISO } from 'date-fns'
import { allPosts } from 'wesjet/static'
export async function getStaticPaths() {
const paths = allPosts.map((post) => post.url)
return {
paths,
fallback: false,
}
}
export async function getStaticProps({ params }) {
const post = allPosts.find((post) => post._raw.flattenedPath === params.slug)
return {
props: {
post,
},
}
}
const PostLayout = ({ post }) => {
return (
<>
<Head>
<title>{post.title}</title>
</Head>
<article className="mx-auto max-w-2xl py-16">
<div className="mb-6 text-center">
<Link href="/">
<a className="text-center text-sm font-bold uppercase text-blue-700">Home</a>
</Link>
</div>
<div className="mb-6 text-center">
<h1 className="mb-1 text-3xl font-bold">{post.title}</h1>
<time dateTime={post.date} className="text-sm text-slate-600">
{format(parseISO(post.date), 'LLLL d, yyyy')}
</time>
</div>
<div className="cl-post-body" dangerouslySetInnerHTML={{ __html: post.body.html }} />
</article>
</>
)
}
export default PostLayout
Notice again that we're importing data from wesjet/static. This is the beauty of wesjet. It has already loaded and shaped our date and keeps the logic in getStaticPaths() and getStaticProps() nice and simple.
Clicking on a post link from the blog page should lead you to a working post page.
You now have a simple blog site with Next.js and wesjet! 🎉
This is just the beginning. Now you can dig in and add all the bells and whistles necessary to build a site with great content using wesjet.