Skip to content

Commit

Permalink
try contentlayer
Browse files Browse the repository at this point in the history
  • Loading branch information
d-ivashchuk committed Apr 7, 2024
1 parent 00ee2f9 commit 6f8953a
Show file tree
Hide file tree
Showing 19 changed files with 2,979 additions and 117 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,6 @@ storybook-static
*storybook.log
# Sentry Config File
.sentryclirc

# contentlayer
.contentlayer
25 changes: 25 additions & 0 deletions content/blog/cascade-ground-zero.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
title: Cascade - open-source SaaS boilerplate
date: 2024-04-12
published: true
description: Cascade is an open-source, free SaaS boilerplate that covers all of the main flows you need to get started with building business logic from day 1.
image: "/images/post-1.png"
---

# Why

Hey, my name is Dima and I've built yet another boilerplate. There are tons of the awesome ones out there on the internet including critically acclaimed [ShipFast](https://shipfa.st/), [Supastarter](https://supastarter.dev/) or [Shipped](https://shipped.club/). They all pack a great offer and can get you started with your business really fast!

I've built a boilerplate not because I wanted to compete with those, but from rather _selfish reasons_. **I've been laid off** two weeks ago and decided to go 100% indie. I've had numerous successful and semi-successful projects in the past including an exit & grew [Lost Pixel](https://www.lost-pixel.com/) from scratch to a promising B2B SaaS. I have my favorite stack, tools and am pretty opinionated about how things should be done. Cascade embodies all of that.

I have bunch of ideas and I don't have time to validate them all. I set a timeline of 6 months to get to a traction that would cover my expenses & lifestyle and **Cascade is a part of that plan**.

I will use it to kickstart multiple SaaS projects and share the progress with you, moreover I will extend the boilerplate with features that I will need for my projects, meaning that you will get a lot of updates and improvements over time.

> **Cascade is not a boilerplate** it is a documentation of a SaaS building journey.
---

# What's included

I want to keep the boilerplate as simple as possible. I pack mostly Open Source & Self Hosted tools into it because I don't like vendor locks as much as you do. You can check out the [extensive docs here](https://stackonfire.mintlify.app/introduction) or [jump straight to the demo](https://cascade.stackonfire.com/app/login) and try it out yourself. The code is [open-source on GitHub](https://github.com/d-ivashchuk/cascade) and contributions are very much welcome!
77 changes: 77 additions & 0 deletions contentlayer.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// contentlayer.config.ts
import { defineDocumentType, makeSource } from "contentlayer/source-files";
import rehypeAutolinkHeadings from "rehype-autolink-headings";
import rehypePrettyCode from "rehype-pretty-code";
import rehypeSlug from "rehype-slug";

export const Post = defineDocumentType(() => ({
name: "Post",
filePathPattern: `blog/**/*.md`,
contentType: "mdx",
fields: {
title: { type: "string", required: true },
image: {
type: "string",
required: true,
},
description: { type: "string", required: true },
date: { type: "date", required: true },
published: {
type: "boolean",
required: true,
default: false,
},
},
computedFields: {
slug: {
type: "string",
resolve: (post) => `/${post._raw.flattenedPath}`,
},
slugAsParams: {
type: "string",
resolve: (doc) => doc._raw.flattenedPath.split("/").slice(1).join("/"),
},
},
}));

export default makeSource({
contentDirPath: "./content",
documentTypes: [Post],
mdx: {
rehypePlugins: [
rehypeSlug,
[
rehypePrettyCode,
{
theme: "dracula",
onVisitLine(node: { children: string | unknown[] }) {
// Prevent lines from collapsing in `display: grid` mode, and allow empty
// lines to be copy/pasted
if (node.children.length === 0) {
node.children = [{ type: "text", value: " " }];
}
},
onVisitHighlightedLine(node: {
properties: { className: string[] };
}) {
node.properties.className.push("line--highlighted");
},
onVisitHighlightedWord(node: {
properties: { className: string[] };
}) {
node.properties.className = ["word--highlighted"];
},
},
],
[
rehypeAutolinkHeadings,
{
properties: {
className: ["subheading-anchor"],
ariaLabel: "Link to section",
},
},
],
],
},
});
3 changes: 2 additions & 1 deletion next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ const config = {};
// Injected content via Sentry wizard below

import { withSentryConfig } from "@sentry/nextjs";
import { withContentlayer } from "next-contentlayer";

export default withSentryConfig(
config,
withContentlayer(config),
{
// For all available options, see:
// https://github.com/getsentry/sentry-webpack-plugin#options
Expand Down
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,24 @@
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"cmdk": "^1.0.0",
"contentlayer": "^0.3.4",
"date-fns": "^3.6.0",
"loops": "^1.0.0",
"lost-pixel": "^3.16.0",
"lucide-react": "^0.363.0",
"next": "^14.1.3",
"next-auth": "^4.24.6",
"next-contentlayer": "^0.3.4",
"next-plausible": "^3.12.0",
"next-themes": "^0.3.0",
"posthog-js": "^1.116.6",
"react": "18.2.0",
"react-day-picker": "^8.10.0",
"react-dom": "18.2.0",
"rehype-autolink-headings": "^7.1.0",
"rehype-pretty-code": "^0.13.1",
"rehype-slug": "^6.0.0",
"remark-gfm": "^4.0.0",
"server-only": "^0.0.1",
"sonner": "^1.4.41",
"superjson": "^2.2.1",
Expand Down
Loading

0 comments on commit 6f8953a

Please sign in to comment.