#How to read local files when deploying to Vercel/Netlify? And how can I prerender without error

6 messages · Page 1 of 1 (latest)

fair thistle
#

So from what I know, deploying to serverless environment like Vercel or Netlify won't have these local files available. Some solution I found online is to configure Vite to copy the markdown files to output directory during build process but I still couldn't manage to do it. Then my second approach is to prerender all routes that need reading local markdown files.

But problem is prerender gives me error at build time too, and the error message is not very clear of why it happened. In the attempt to recreate the error, I found that prerender only gives me error if I try to read local markdown files with search params. Without search params it's all good. Here's all the code that I think we all need to debug. Note that the markdown file does exist there.

Github: https://github.com/bobdeei/tanstack-start-ssg/

GitHub

Contribute to bobdeei/tanstack-start-ssg development by creating an account on GitHub.

#
// src/utils/readMd.ts
import fs from "node:fs/promises";
import path from "node:path";
import { createServerFn } from "@tanstack/react-start";

export const readMd = createServerFn()
    .inputValidator((data: { filePath: string[] }) => data)
    .handler(async ({ data: { filePath } }) => {
        return fs.readFile(path.join(path.resolve(), ...filePath), "utf-8");
    });
#
// src/routes/index.tsx
import { createFileRoute, Link } from "@tanstack/react-router";
import { marked } from "marked";
import z from "zod";
import { readMd } from "#/utils";

export const Route = createFileRoute("/")({
    loaderDeps: ({ search }) => search,
    loader: async ({ deps: { slug = "post1" } }) => {
        const basePath = "src/data";

        const html = await readMd({
            data: { filePath: [basePath, `${slug}.md`] },
        }).then(marked);

        return { html };
    },
    validateSearch: z.object({
        slug: z.string().optional(),
    }),
    component: App,
});

function App() {
    const { html } = Route.useLoaderData();

    return (
        <main className="page-wrap px-4 pb-8 pt-14">
            <div className="space-x-4">
                <Link to="/" search={{ slug: "post1" }}>
                    Post 1
                </Link>
            </div>

            <div
                className="prose border rounded-2xl bg-cyan-800 prose-p:text-white prose-headings:text-white"
                dangerouslySetInnerHTML={{ __html: html }}
            />

        </main>
    );
}
#

Error message

[prerender] Prerendering pages...
[prerender] Concurrency: 8
[prerender] Crawling: /
[prerender] Crawling: /about
[prerender] Crawling: /?slug=post1
file:///Users/dnguyen/Downloads/code/tanstack-start-ssg/node_modules/@tanstack/start-plugin-core/dist/esm/prerender.js:103
                                                throw new Error(`Failed to fetch ${page.path}: ${res.statusText}`, { cause: res });
                                                      ^

Error: Failed to fetch /?slug=post1: Internal Server Error
    at file:///Users/dnguyen/Downloads/code/tanstack-start-ssg/node_modules/@tanstack/start-plugin-core/dist/esm/prerender.js:103:13
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
    at async file:///Users/dnguyen/Downloads/code/tanstack-start-ssg/node_modules/@tanstack/start-plugin-core/dist/esm/queue.js:35:12 {
  [cause]: Response {
fierce plank
#

please provide a complete minimal example repo

fair thistle