Deploying
Gonna keep this one relatively short. I'll highlight what was wrong with my first attempt and then dive into how I resolved the issue.
First Attempt
Setting up Vercel was as easy as "New Project" and it recognizing my repo as a Remix.run project. Below is the very first thing I saw when I visited my Vercel site!
Error: ENOENT: no such file or directory, scandir '/var/task/output/server/pages/blog'
So I dug around the Remix docs & Discord server. Long story short, Vercel only uses the build output. My blog
folder is not a part of that build output.
Adding GitHub
To get around the limitation of not having access to my content files, I'll use the GitHub API to read my content. I added app/util/github.server.ts
to manage calls to GitHub.
import { Octokit } from "@octokit/rest";
import invariant from "tiny-invariant";
const octokit = new Octokit({
auth: process.env.GITHUB_TOKEN
});
export const getBlogPostDirFiles = async () => {
const { data } = await octokit.repos.getContent({
owner: "vivalldi",
repo: "vivalldi.dev",
path: "blog"
});
invariant(Array.isArray(data), "Expected data to be an array");
return await Promise.all(
data.map(async fileData => {
invariant(fileData.download_url, "Download URL is missing");
let resp = await fetch(fileData.download_url);
let content = await resp.text();
return {
...fileData,
content
};
})
);
};
export const getBlogPostFile = async (slug: string) => {
const { data } = await octokit.repos.getContent({
owner: "vivalldi",
repo: "vivalldi.dev",
path: `blog/${slug}.md`
});
invariant(!Array.isArray(data), "Response malformed");
invariant("content" in data, "Response not a file");
return Buffer.from(data.content, "base64").toString("utf8");
};
I also moved app/blog.util.ts
to app/util/blog.ts
. This just helps tidy things up.
The notable changes to blog.ts
are that I call getBlogPostFile
to get the post data rather than fs
. The same goes for listing blog posts.