Next.js Discord

Discord Forum

Collecting page data ...TypeError: (0 , r.createContext) is not a function

Answered
Bombay posted this in #help-forum
Open in Discord
BombayOP
I'm trying to do npm run build and i get this error all the time:

> backend-stash@0.1.0 build
> next build               

   â–² Next.js 14.0.4
   - Environments: .env

 ✓ Creating an optimized production build    
 ✓ Compiled successfully
 ✓ Linting and checking validity of types    
   Collecting page data  ...TypeError: (0 , r.createContext) is not a function
    at 50153 (C:\Users\DT User\Desktop\Websites\Artifex\.next\server\chunks\4095.js:4:19726)
    at t (C:\Users\DT User\Desktop\Websites\Artifex\.next\server\webpack-runtime.js:1:143)
    at 47950 (C:\Users\DT User\Desktop\Websites\Artifex\.next\server\app\api\dashboard\freelancer\products\create\route.js:1:3785)
    at t (C:\Users\DT User\Desktop\Websites\Artifex\.next\server\webpack-runtime.js:1:143)
    at 49232 (C:\Users\DT User\Desktop\Websites\Artifex\.next\server\app\api\dashboard\freelancer\products\create\route.js:1:1495)
    at t (C:\Users\DT User\Desktop\Websites\Artifex\.next\server\webpack-runtime.js:1:143)
    at r (C:\Users\DT User\Desktop\Websites\Artifex\.next\server\app\api\dashboard\freelancer\products\create\route.js:1:5967)
    at C:\Users\DT User\Desktop\Websites\Artifex\.next\server\app\api\dashboard\freelancer\products\create\route.js:1:6025
    at t.X (C:\Users\DT User\Desktop\Websites\Artifex\.next\server\webpack-runtime.js:1:1285)
    at C:\Users\DT User\Desktop\Websites\Artifex\.next\server\app\api\dashboard\freelancer\products\create\route.js:1:5980

> Build error occurred
Error: Failed to collect page data for /api/dashboard/freelancer/products/create
    at C:\Users\DT User\Desktop\Websites\Artifex\node_modules\next\dist\build\utils.js:1220:15
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  type: 'Error'
}
   Collecting page data  .
Answered by Bombay
i just created two files
View full answer

84 Replies

@Bombay I'm trying to do `npm run build` and i get this error all the time: js > backend-stash@0.1.0 build > next build ▲ Next.js 14.0.4 - Environments: .env ✓ Creating an optimized production build ✓ Compiled successfully ✓ Linting and checking validity of types Collecting page data ...TypeError: (0 , r.createContext) is not a function at 50153 (C:\Users\DT User\Desktop\Websites\Artifex\.next\server\chunks\4095.js:4:19726) at t (C:\Users\DT User\Desktop\Websites\Artifex\.next\server\webpack-runtime.js:1:143) at 47950 (C:\Users\DT User\Desktop\Websites\Artifex\.next\server\app\api\dashboard\freelancer\products\create\route.js:1:3785) at t (C:\Users\DT User\Desktop\Websites\Artifex\.next\server\webpack-runtime.js:1:143) at 49232 (C:\Users\DT User\Desktop\Websites\Artifex\.next\server\app\api\dashboard\freelancer\products\create\route.js:1:1495) at t (C:\Users\DT User\Desktop\Websites\Artifex\.next\server\webpack-runtime.js:1:143) at r (C:\Users\DT User\Desktop\Websites\Artifex\.next\server\app\api\dashboard\freelancer\products\create\route.js:1:5967) at C:\Users\DT User\Desktop\Websites\Artifex\.next\server\app\api\dashboard\freelancer\products\create\route.js:1:6025 at t.X (C:\Users\DT User\Desktop\Websites\Artifex\.next\server\webpack-runtime.js:1:1285) at C:\Users\DT User\Desktop\Websites\Artifex\.next\server\app\api\dashboard\freelancer\products\create\route.js:1:5980 > Build error occurred Error: Failed to collect page data for /api/dashboard/freelancer/products/create at C:\Users\DT User\Desktop\Websites\Artifex\node_modules\next\dist\build\utils.js:1220:15 at process.processTicksAndRejections (node:internal/process/task_queues:95:5) { type: 'Error' } Collecting page data .
BombayOP
Here's /api/dashboard/freelancer/products/create code, its saying its from there:

import { NextResponse } from "next/server";

import { validateRichTextEditorContent } from "@/lib/editor/validate-rich-text-editor-content";
import prisma from "@/lib/prismadb";

import getCurrentUser from "@/actions/getCurrentUser";

/**
 * Create a new product with a POST request.
 * @param {Request} request - Request object with product data.
 */
export async function POST(request: Request) {
  // Check if user is logged in.
  const currentUser = await getCurrentUser();
  if (!currentUser?.id)
    return new NextResponse("Unauthorized", { status: 401 });

  // Check if bad request.
  const { information, detailedInformation, images, files } =
    await request.json();

  if (!information || !detailedInformation || !images || !files)
    return new NextResponse("Bad Request", { status: 400 });

  // Check if product images are valid.
  const productImagesFiltered = images.filter(
    (image: null | undefined) => image !== null && image !== undefined
  );
  if (!productImagesFiltered.length)
    return new NextResponse("At least 1 picture needs to be uploaded.", {
      status: 400,
    });

  const productFilesFiltered = files.filter(
    (file: null | undefined) => file !== null && file !== undefined
  );

  if (!productFilesFiltered.length)
    return new NextResponse("At least 1 file needs to be uploaded.", {
      status: 400,
    });

  // Check if product already exists.
  const productId = `${new Date()
    .toISOString()
    .slice(0, 10)
    .replace(/-/g, "")}-${Math.floor(Math.random() * 10000)}`;
  if (await prisma.product.findUnique({ where: { productId } }))
    return new NextResponse("Please try again, there was an issue.", {
      status: 400,
    });
  // check if product description & documentation is valid
  const descriptionIsValid = validateRichTextEditorContent.parse(
    detailedInformation.description
  );
  const documentationIsValid = validateRichTextEditorContent.parse(
    detailedInformation.documentation
  );

  if (!descriptionIsValid || !documentationIsValid) {
    return new NextResponse(
      "Product description or documentation is invalid.",
      {
        status: 400,
      }
    );
  }

  let discountedPrice = information.discounted
    ? information.discountedPrice
    : undefined;
  const testedVersionStrings = information.testedVersions
    ? information.testedVersions.map((version: { value: any }) => version.value)
    : undefined;
  const supportedSoftwaresStrings = information.supported_softwares
    ? information.supported_softwares.map(
        (software: { value: any }) => software.value
      )
    : undefined;

  // Create product.
  await prisma.product.create({
    data: {
      productId: productId,
      productOwnerId: currentUser.id,
      name: information.productName,
      game: information.game,
      donationLink: information.donationLink,
      sourceCode: information.sourceCode,
      category: information.category,
      price: parseInt(information.price),
      discountPrice: parseInt(discountedPrice),
      description: detailedInformation.description,
      documentation: detailedInformation.documentation,
      userId: currentUser.id,
      productVersion: "1.0.0",

      nativeVersion: information.nativeVersion,
      testedVersion: testedVersionStrings as string[],
      type: information.type,
      theme: information.theme,
      supported_softwares: supportedSoftwaresStrings as string[],

      images: productImagesFiltered as string[],
      files: productFilesFiltered as string[],
    },
  });

  // Return response.
  return new NextResponse("Product created", { status: 200 });
}
@Bombay Here's `/api/dashboard/freelancer/products/create` code, its saying its from there: js import { NextResponse } from "next/server"; import { validateRichTextEditorContent } from "@/lib/editor/validate-rich-text-editor-content"; import prisma from "@/lib/prismadb"; import getCurrentUser from "@/actions/getCurrentUser"; /** * Create a new product with a POST request. * @param {Request} request - Request object with product data. */ export async function POST(request: Request) { // Check if user is logged in. const currentUser = await getCurrentUser(); if (!currentUser?.id) return new NextResponse("Unauthorized", { status: 401 }); // Check if bad request. const { information, detailedInformation, images, files } = await request.json(); if (!information || !detailedInformation || !images || !files) return new NextResponse("Bad Request", { status: 400 }); // Check if product images are valid. const productImagesFiltered = images.filter( (image: null | undefined) => image !== null && image !== undefined ); if (!productImagesFiltered.length) return new NextResponse("At least 1 picture needs to be uploaded.", { status: 400, }); const productFilesFiltered = files.filter( (file: null | undefined) => file !== null && file !== undefined ); if (!productFilesFiltered.length) return new NextResponse("At least 1 file needs to be uploaded.", { status: 400, }); // Check if product already exists. const productId = `${new Date() .toISOString() .slice(0, 10) .replace(/-/g, "")}-${Math.floor(Math.random() * 10000)}`; if (await prisma.product.findUnique({ where: { productId } })) return new NextResponse("Please try again, there was an issue.", { status: 400, });
could you show the code on getCurrentUser
BombayOP
Can i use pastebin? its long
but im not sure its from there
it used to build fine
before
@Bombay Can i use pastebin? its long
sure
BombayOP
i saw that somewhere they say its due to pusher?
@Bombay https://pastebin.com/n95B3HrG
and validateRichTextEditorContent
@Ray and `validateRichTextEditorContent`
BombayOP
import { getSchema, JSONContent } from "@tiptap/core";
import { Node } from "prosemirror-model";
import z from "zod";

import { richTextEditorExtensions } from "./extensions";

const validator = (doc: JSONContent): boolean => {
  try {
    const schema = getSchema(richTextEditorExtensions);
    const contentNode = Node.fromJSON(schema, doc);

    contentNode.check();

    return true;
  } catch (e) {
    return false;
  }
};

export const validateRichTextEditorContent = z.custom(
  (doc) => validator(doc as JSONContent),
  {
    message: "Invalid JSONContent",
  }
);
could it be due to pusher?
@Bombay could it be due to pusher?
don't see any code related to pusher here
BombayOP
oh yeah i saw prisma and thought it was pusher.. sorry my mistake
on another route
let me edit everything
so the problem is not here
...TypeError: (0 , r.createContext) is not a function look like you are trying to use context api on server or something
BombayOP
yep that fixed it
found it?
BombayOP
it built
im not sure if i am
oh you mean it build if change the name to _route?
@Bombay yeah
ok try this
//const currentUser = await getCurrentUser();
const currentUser = {}
if (!currentUser?.id)
return new NextResponse("Unauthorized", { status: 401 });
BombayOP
how will that work?
i mean
there isnt id
on currentuser
if its like that
@Bombay how will that work?
so it return 401
just testing if it build or not
BombayOP
yeah but TS2339: Property 'id' does not exist on type '{}'.
typescript
const currentUser: {id?: string} = {}
BombayOP
i did this

  const currentUser = {}
  if (!currentUser)
    return new NextResponse("Unauthorized", { status: 401 });
PS C:\Users\DT User\Desktop\Websites\Artifex> npm run build

> backend-stash@0.1.0 build
> next build               

   â–² Next.js 14.0.4
   - Environments: .env                     
                                            
 ✓ Creating an optimized production build    
 ✓ Compiled successfully                     
 ✓ Linting and checking validity of types    
   Collecting page data  ...TypeError: (0 , sE.createContext) is not a function
    at 46738 (C:\Users\DT User\Desktop\Websites\Artifex\.next\server\app\api\dashboard\freelancer\products\create\route.js:4:106384)
    at t (C:\Users\DT User\Desktop\Websites\Artifex\.next\server\webpack-runtime.js:1:143)
    at n (C:\Users\DT User\Desktop\Websites\Artifex\.next\server\app\api\dashboard\freelancer\products\create\route.js:4:151524)
    at C:\Users\DT User\Desktop\Websites\Artifex\.next\server\app\api\dashboard\freelancer\products\create\route.js:4:151567
    at t.X (C:\Users\DT User\Desktop\Websites\Artifex\.next\server\webpack-runtime.js:1:1285)
    at C:\Users\DT User\Desktop\Websites\Artifex\.next\server\app\api\dashboard\freelancer\products\create\route.js:4:151537
    at Object.<anonymous> (C:\Users\DT User\Desktop\Websites\Artifex\.next\server\app\api\dashboard\freelancer\products\create\route.js:4:151595)
    at Module._compile (node:internal/modules/cjs/loader:1376:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1435:10)
    at Module.load (node:internal/modules/cjs/loader:1207:32)

> Build error occurred
Error: Failed to collect page data for /api/dashboard/freelancer/products/create
    at C:\Users\DT User\Desktop\Websites\Artifex\node_modules\next\dist\build\utils.js:1220:15
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  type: 'Error'
}
still
  // Check if user is logged in.
  const currentUser: {id: string | null} = {
    id: null,
  }
  if (!currentUser?.id)
    return new NextResponse("Unauthorized", { status: 401 });
BombayOP
yeah
@Bombay yeah
uncomment the code that related to validateRichTextEditorContent
BombayOP
yeah give me a sec
seems to be that
@Bombay seems to be that
ok revert it back and only uncomment the code related to richTextEditorExtensions
BombayOP
okay so
i think its this
what is it?
BombayOP
mentionSuggestionOptions
import type { MentionOptions } from "@tiptap/extension-mention";
import { ReactRenderer } from "@tiptap/react";
import axios from "axios";
import tippy, { type Instance as TippyInstance } from "tippy.js";

import { SuggestionList, type SuggestionListRef } from "./suggestion-list";

export type MentionSuggestion = {
  id: string;
  mentionLabel: string;
  image: string | null;
};

/**
 * Workaround for the current typing incompatibility between Tippy.js and Tiptap
 * Suggestion utility.
 *
 * @see https://github.com/ueberdosis/tiptap/issues/2795#issuecomment-1160623792
 *
 * Adopted from
 * https://github.com/Doist/typist/blob/a1726a6be089e3e1452def641dfcfc622ac3e942/stories/typist-editor/constants/suggestions.ts#L169-L186
 */
const DOM_RECT_FALLBACK: DOMRect = {
  bottom: 0,
  height: 0,
  left: 0,
  right: 0,
  top: 0,
  width: 0,
  x: 0,
  y: 0,
  toJSON() {
    return {};
  },
};

export const mentionSuggestionOptions: MentionOptions["suggestion"] = {
  // Replace this `items` code with a call to your API that returns suggestions
  // of whatever sort you like (including potentially additional data beyond
  // just an ID and a label). It need not be async but is written that way for
  // the sake of example.
  items: async ({ query }): Promise<MentionSuggestion[]> => {
    // call api here using axios
    const response = await axios.get(
      `/api/dashboard/freelancer/products/mention-user/${
        query || "70248747188290124442124"
      }`
    );

    const users = response.data;

    return users.map((user: { id: string; name: string; image: string }) => ({
      id: user.id,
      mentionLabel: user.name,
      image: user.image || null,
    }));
  },

  render: () => {
    let component: ReactRenderer<SuggestionListRef> | undefined;
    let popup: TippyInstance | undefined;
    return {
      onStart: (props) => {
        component = new ReactRenderer(SuggestionList, {
          props,
          editor: props.editor,
        });

        popup = tippy("body", {
          getReferenceClientRect: () =>
            props.clientRect?.() ?? DOM_RECT_FALLBACK,
          appendTo: () => document.body,
          content: component.element,
          showOnCreate: true,
          interactive: true,
          trigger: "manual",
          placement: "bottom-start",
        })[0];
      },

      onUpdate(props) {
        component?.updateProps(props);

        popup?.setProps({
          getReferenceClientRect: () =>
            props.clientRect?.() ?? DOM_RECT_FALLBACK,
        });
      },

      onKeyDown(props) {
        if (props.event.key === "Escape") {
          popup?.hide();
          return true;
        }

        if (!component?.ref) {
          return false;
        }

        return component.ref.onKeyDown(props);
      },

      onExit() {
        popup?.destroy();
        component?.destroy();

        // Remove references to the old popup and component upon destruction/exit.
        // (This should prevent redundant calls to `popup.destroy()`, which Tippy
        // warns in the console is a sign of a memory leak, as the `suggestion`
        // plugin seems to call `onExit` both when a suggestion menu is closed after
        // a user chooses an option, *and* when the editor itself is destroyed.)
        popup = undefined;
        component = undefined;
      },
    };
  },
};
look like its is client side thing
could you validate that on client
BombayOP
  Mention.configure({
    HTMLAttributes: {
      class: "text-[#6366F1] underline underline-offset-4 font-medium",
    },
    suggestion: mentionSuggestionOptions,
  }),
this
causes
the error
    suggestion: mentionSuggestionOptions,
could you show the code on mentionSuggestionOptions
BombayOP
yeah its this
@Bombay js import type { MentionOptions } from "@tiptap/extension-mention"; import { ReactRenderer } from "@tiptap/react"; import axios from "axios"; import tippy, { type Instance as TippyInstance } from "tippy.js"; import { SuggestionList, type SuggestionListRef } from "./suggestion-list"; export type MentionSuggestion = { id: string; mentionLabel: string; image: string | null; }; /** * Workaround for the current typing incompatibility between Tippy.js and Tiptap * Suggestion utility. * * @see https://github.com/ueberdosis/tiptap/issues/2795#issuecomment-1160623792 * * Adopted from * https://github.com/Doist/typist/blob/a1726a6be089e3e1452def641dfcfc622ac3e942/stories/typist-editor/constants/suggestions.ts#L169-L186 */ const DOM_RECT_FALLBACK: DOMRect = { bottom: 0, height: 0, left: 0, right: 0, top: 0, width: 0, x: 0, y: 0, toJSON() { return {}; }, }; export const mentionSuggestionOptions: MentionOptions["suggestion"] = { // Replace this `items` code with a call to your API that returns suggestions // of whatever sort you like (including potentially additional data beyond // just an ID and a label). It need not be async but is written that way for // the sake of example. items: async ({ query }): Promise<MentionSuggestion[]> => { // call api here using axios const response = await axios.get( `/api/dashboard/freelancer/products/mention-user/${ query || "70248747188290124442124" }` ); const users = response.data; return users.map((user: { id: string; name: string; image: string }) => ({ id: user.id, mentionLabel: user.name, image: user.image || null, })); }, render: () => { let component: ReactRenderer<SuggestionListRef> | undefined; let popup: TippyInstance | undefined;
BombayOP
.
import { ReactRenderer } from "@tiptap/react";
should be this
BombayOP
so what can i do to fix it?
@Bombay so what can i do to fix it?
I don't know what it does
@Bombay so what can i do to fix it?
could you validate that on client when the result come back
BombayOP
validate what?
or validate before submit
@Bombay validate what?
validateRichTextEditorContent
@Ray or validate before submit
BombayOP
is it safe tho
no if they hit your endpoint directly instead of your form
@Bombay validate what?
does this work?
export const mentionSuggestionOptions: MentionOptions["suggestion"] = {
  // Replace this `items` code with a call to your API that returns suggestions
  // of whatever sort you like (including potentially additional data beyond
  // just an ID and a label). It need not be async but is written that way for
  // the sake of example.
  items: async ({ query }): Promise<MentionSuggestion[]> => {
    // call api here using axios
    const response = await axios.get(
      `/api/dashboard/freelancer/products/mention-user/${
        query || "70248747188290124442124"
      }`
    );

    const users = response.data;

    return users.map((user: { id: string; name: string; image: string }) => ({
      id: user.id,
      mentionLabel: user.name,
      image: user.image || null,
    }));
  }
}
BombayOP
i just created two files
Answer
BombayOP
its working
thank you so much
nice
no prob
BombayOP
wrong solution xD