I followed a tutorial from yt Josh tried coding
https://www.youtube.com/watch?v=06g6YJ6JCJU
I am trying to make an app to manage entries. The functionality itself locally is in the pipeline. But due to the fact that I wanted to see what hosting such a site on Cloudflare Pages looks like. I decided to upload.
The site locally works fine and on paths /api returns json.
After deploying it in cloudflare, however, it returns HTML and gets an error
Uncaught (in promise) SyntaxError: Unexpected token '<', "<!doctype ".... is not valid JSON
I see in the web stats that the API response is an html element containing the same start page.
Does cloudflare have json response blocked?
Below is the configuration of my express server. JS and payload.config.ts
server.ts (express.js serwer configuration)
import express from "express";
import { getPayLoadClient } from "./get-payload";
import { nextApp, nextHandler } from "./next-utils";
import payload from "payload";
import * as trpcExpress from "@trpc/server/adapters/express";
import { appRouter } from "./trpc";
import { inferAsyncReturnType } from "@trpc/server";
import nextBuild from "next/dist/build";
import path from "path";
import { IncomingMessage } from "http";
const app = express();
const PORT = Number(process.env.PORT) || 3000;
const createContext = ({
req,
res,
}: trpcExpress.CreateExpressContextOptions) => ({
req,
res,
});
export type ExpressContext = inferAsyncReturnType<typeof createContext>;
export type WebhookRequest = IncomingMessage & {
rawBody: Buffer;
};
const start = async () => {
const payload = await getPayLoadClient({
initOptions: {
express: app,
onInit: async (cms) => {
cms.logger.info(`Admin Url ${cms.getAdminURL}`);
},
},
});
if (process.env.NEXT_BUILD) {
app.listen(PORT, async () => {
payload.logger.info("Next.js is building for production");
// @ts-expect-error
await nextBuild(path.join(__dirname, "../"));
process.exit();
});
return;
}
app.use(express.json());
app.use(
"/api/trpc",
trpcExpress.createExpressMiddleware({
router: appRouter,
createContext,
})
);
app.use((req, res) => nextHandler(req, res));
nextApp.prepare().then(() => {
app.listen(PORT, async () => {
});
});
};
start();
Payload.config.ts
import { mongooseAdapter } from "@payloadcms/db-mongodb";
import { buildConfig } from "payload/config";
import { slateEditor } from "@payloadcms/richtext-slate";
import { webpackBundler } from "@payloadcms/bundler-webpack";
import path from "path";
import { Users } from "./collections/Users";
import dotenv from "dotenv";
import { Invoices } from "./collections/invoices/invoices";
import { Cars } from "./collections/cars/cars";
import { Media } from "./collections/invoices/media";
import { Collected } from "./collections/collected/collected";
dotenv.config({
path: path.resolve(__dirname, "../.env"),
});
export default buildConfig({
serverURL: process.env.NEXT_PUBLIC_SERVER_URL || "",
collections: [Users, Invoices, Cars, Media, Collected],
localization: {
locales: ["pl"],
defaultLocale: "pl",
fallback: true,
},
admin: {
user: "users",
bundler: webpackBundler(),
meta: {
titleSuffix: "- Page Title",
favicon: "/favicon.ico",
ogImage: "/thumbnail.jpg",
},
},
rateLimit: {
max: 2000,
},
editor: slateEditor({}),
db: mongooseAdapter({
url: process.env.MONGODB_URL!,
}),
typescript: {
outputFile: path.resolve(__dirname, "payload-types.ts"),
},
});
Expects responses from the API to be returned for the frontend in JSON format
This is the hook that fetch for the data.
// hooks/useUser.ts
import { useState, useEffect } from "react";
import { User } from "../payload-types";
const useUser = () => {
const [user, setUser] = useState<User | null>(null);
useEffect(() => {
const fetchUser = async () => {
try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_SERVER_URL}/api/users/me`,
{
headers: {
credentials: "include",
},
}
);
if (!response.ok) {
throw new Error("Failed to fetch user");
}
const data = await response.json();
console.log(data);
console.log(response); //added for debugging
setUser(data.user);
} catch (error) {
console.error("Error fetching user:", error);
setUser(null);
}
};
fetchUser();
}, []);
return user;
};
export default useUser;