Next.js Discord

Discord Forum

Can't traverse filesystem in production using `fast-glob` and `process.cwd()`

Unanswered
Oriental posted this in #help-forum
Open in Discord
OrientalOP
import glob from 'fast-glob'
import path from 'path'

const BlogPage = async () => {
  let pages = await glob('**/*.mdx', {
    cwd: `${path.resolve()}/app/[locale]/home/blog`,
  })

  return (
    <></>
  )
}

export default BlogPage


This page lives under app/[locale]/home/blog/page.tsx, it does fetch my blog pages in development, but it DOES NOT find the pages in production. The pages array just comes empty { pages: [] } if i console.log({ pages }), but i get them in development.

3 Replies

Black Caiman
Hmm, never used it but maybe the [] is throwing it off? Try logging what cwd is?
If it helps, I wrote this for myself
import path from "path";
import fs from "fs";

async function getMarkdownFilesRecursive(dir: string): Promise<string[]> {
  const entries = await fs.promises.readdir(dir, { withFileTypes: true });

  const filesArray = await Promise.all(
    entries.map(async (entry) => {
      const fullPath = path.join(dir, entry.name);

      if (
        entry.isFile() &&
        entry.name.startsWith("page") &&
        entry.name.endsWith(".md")
      ) {
        return [fullPath];
      }

      if (entry.isDirectory()) {
        return getMarkdownFilesRecursive(fullPath);
      }

      return [];
    }),
  );

  return filesArray.flat();
}

export async function getMarkdownAbsolutePaths() {
  const projectRoot = process.cwd();
  const contentDir = path.join(projectRoot, "content");

  const files = await getMarkdownFilesRecursive(contentDir);
  return files //.filter(onlyUnique);
}

since I wanted only any page.md under the content directory at root (i figure using nextjs conventions might be good, esp since index.md breaks sometimes and i like to bundle assets in the same directory). Might eventually add i18n with page.<lang>.md but idk yet. Potentially just using fs read dir sync is simpler :amicablethink:


This could be modified pretty trivially to support what you want?
Black Caiman
I refactored a bit. I'm now using globby, which is built on top of fast-glob, like so:
import path from "path";
import fs from "fs";
import { globbySync } from "globby";
import matter from "gray-matter";

const projectRoot = process.cwd();
const contentDir = path.join(projectRoot, "content");
// TODO: turn this into `"**/page*.md"` when dealing with i18n
// eg page.es.md will be spanish
const contentPattern = ["**/page.md"];

export function getAllContentData() {
  const filePaths = globbySync(contentPattern, { cwd: contentDir });

  return filePaths.map((filePath) => {
    const absFilePath = path.join(contentDir, filePath);
    const fileContent = fs.readFileSync(absFilePath, "utf-8");

    const slug = filePath.split("/").slice(0, -1).join("/");
    const { data, content } = matter(fileContent);

    return {
      absFilePath,
      rawContent: fileContent,
      slug,
      frontmatter: data,
      content,
    };
  });
}

hopefully something helps ya :amicablethink: