#Cloudflare's Pages Functions not working

35 messages · Page 1 of 1 (latest)

gentle harness
#

Hi,
I'm trying to use a Pages Function on Cloudflare, but I'm starting to lose hope. It's basically my first time playing with it...

so I made the functions folder in the root of the project. In there I made a simple script:

export const onRequest = async (context) => {
  return new Response("TEST");
};

After that I ran npm run build and npx wrangler pages dev ./dist.
Then when I try to hit: http://127.0.0.1:8788/test
It only returns my index page. So there is some problem.

This is my Astro config:

import { defineConfig } from 'astro/config';
import tailwind from '@astrojs/tailwind';
import react from '@astrojs/react';
import cloudflare from '@astrojs/cloudflare';

export default defineConfig({
  output: 'static',
  adapter: cloudflare(),
  integrations: [tailwind(), react()],
});

Here's wrangler config:

name = "test-project"
pages_build_output_dir = "dist"
compatibility_date = "2025-10-20"

Here's _routes.json:

{
  "version": 1,
  "include": [
    "/*"
  ],
  "exclude": [
    "/",
    "/_astro/*",
    "/favicon.svg",
    "/admin/config.yml",
    "/admin/index.html",
    "/about",
    "/booking",
    "/floral-arrangements",
    "/portfolio",
    "/pricing"
  ]
}

I'm not sure if I'm missing any configuration or not doing something important in order for the functions to work.
I did try to run the project both locally and on CF with the same result, pages functions don't work.
I'll much appreaciate any help!

royal storm
#

What type of functions are you trying to make? In general rh astro Cloudflare adapter is meant for just astro stuff not writing pages functions directly

gentle harness
#

just a simple fetch.. I'll use that for Google and Instagram API. but tried just the simple one I shared which doesn't work either

royal storm
#

can you write it as just normal astro code?

gentle harness
#

well I had it in pages/api/... , but I found out, that Cloudflare doesn't support that, instead you can use their Pages Functions. But I can't seem to figure out, how to make that work

#

because I want the api to work with a server island..

royal storm
#

The Cloudflare adapter for astro will take your astro code and turn it into the necessary pages functions to get it all to work on Cloudflare

#

So you can use pages/api/example.ts etc

gentle harness
#

really? I didn't know that..
I tried that also tho, before I tried the Pages Functions and that didn't work either.

is there any docs for that? I tried to read both on Astro docs and Cloudflare

royal storm
#

If you want to share some code from the endpoint you tried before we can try to debug

gentle harness
#

sure, this is the instagram API, maybe the env is the problem, but I bealive it worked before when it was static...

export const prerender = false;

import type { APIRoute } from 'astro';

export const GET: APIRoute = async () => {
  const token = import.meta.env.INSTAGRAM_TOKEN;

  if (!token) {
    console.error('INSTAGRAM_TOKEN environment variable is not set');
    return new Response(JSON.stringify({ 
      error: 'Instagram configuration error', 
      data: [] 
    }), {
      status: 500,
      headers: { 'Content-Type': 'application/json' }
    });
  }

  const url = `https://graph.instagram.com/me/media?fields=id,media_url,caption,permalink,media_type,timestamp&limit=24&access_token=${token}`;

  try {
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), 10000);

    const res = await fetch(url, {
      signal: controller.signal,
      headers: {
        'Accept': 'application/json'
      }
    });

    clearTimeout(timeoutId);

    if (!res.ok) {
      const errorText = await res.text();
      console.error(`Instagram API error (${res.status}): ${errorText}`);
      throw new Error(`Instagram API responded with status: ${res.status}`);
    }

    const data = await res.json();

    if (!data || !Array.isArray(data.data)) {
      console.error('Invalid response format from Instagram API:', data);
      throw new Error('Invalid response format from Instagram API');
    }

    return new Response(JSON.stringify(data), {
      status: 200,
      headers: {
        'Content-Type': 'application/json',
        'Cache-Control': 'public, max-age=3600'
      },
    });
  } catch (error: unknown) {
    console.error('Instagram API error:', error);

can't send longer messages, so it's not complete 😄

#

maybe this is a better example, this is the google one..

// src/pages/api/google.ts
export const prerender = false;

import type { APIRoute } from 'astro';

export const GET: APIRoute = async () => {
  const GOOGLE_API_KEY = import.meta.env.GOOGLE_API_KEY;

  try {
    const reviewsResponse = await fetch(
      `https://places.googleapis.com/v1/places/ChIJ5w24VAba4H1mhxBAqQ?fields=reviews&key=${GOOGLE_API_KEY}`
    );

    if (!reviewsResponse.ok) {
      return new Response(JSON.stringify({ error: 'Failed to fetch reviews' }), { status: 400 });
    }

    const reviewsData = await reviewsResponse.json();

    return new Response(JSON.stringify({
      reviews: reviewsData.reviews || [],
    }), {
      status: 200,
      headers: { 'Content-Type': 'application/json' }
    });
  } catch (error) {
    console.error('Error fetching data:', error);
    return new Response(JSON.stringify({ error: 'Internal server error' }), { status: 500 });
  }
};
royal storm
#

It probably is related to the env but did you get any specific error from this?

#

I’d probably work up to your actual goal to verify you’ve got everything working in astro-cloudflare world first, start with a simple get etc

uneven cloak
#

So env is interesting on Cloudflare. I develop exclusively on Cloudflare. You want to add your variables inside your .env and then run npx wrangler types or pnpm run cf-typegen and that should give you the types you need. Then you access your env variables inside of ctx.locals.runtime.env.KEY

https://github.com/hkbertoson/pages-testing

You dont need a seperate functions directory. Just the API Endpoints are fine. In that Repo. Add an .env file and run pnpm run cf-typegen and then you can get the Types from it.

GitHub

Contribute to hkbertoson/pages-testing development by creating an account on GitHub.

gentle harness
#

yes, so I can confirm, the problem was in the env. Thank you guys for your advices! I'll try to figure it out.

quartz cargoBOT
#
If your issue is resolved, please help by doing the following two steps:
  1. From the ellipses (3-dot menu) in the top-right corner of the post (not the first message), edit the tags to include the Solved tag.
  2. From the same ellipses, select Close Post.
    Your post will still be available to search and can be re-opened simply by replying in it. Closing a post moves it down with older posts, so we can more easily focus on issues that still need to be resolved.
    Thank you for your help!
gentle harness
uneven cloak
#

If you look at the repo I linked. It has it.

gentle harness
#

ok I see it on the github... sorry

import type { APIRoute } from "astro";

export const GET: APIRoute = async (ctx) => {
const SUPER_SECRET_KEY = ctx.locals.runtime.env.SUPER_SECRET_KEY

return new Response(SUPER_SECRET_KEY, {
    headers: { "Content-Type": "application/json" },
});

}

uneven cloak
#

All good

gentle harness
#

thank you, I'll try that out and let you know

gentle harness
# uneven cloak All good

ok, so now the responses top the endpoints are 200, but the server islands don't render for some reason. the same was true when locally trying it...
instead of the components I get this: [object Object] [object Object]

would you by any chance be willing to look at my github?

uneven cloak
#

Sure!

gentle harness
uneven cloak
#

I dont see why it would give [object Object] but I dont have a key for Insta and Google so I cant test it lol

gentle harness
#

ye 🙁 I mean npx astro dev works fine, but when I build with npm run build and then run it with npx wrangler pages dev, it does the object thing...

#

and on cloudflare the same

uneven cloak
#

Can you add a console.log(posts) and a console.log(reviews) to your components and then run a Build and see what it outputs?

gentle harness
#

well in local with wrangler pages it actually prints out everything just fine

#

so the reviews json is just fine in the console, but even this just spits out [object Object]

---
import ReviewCard from "./ReviewCard.astro";
import ErrorBanner from "./utils/ErrorBanner.astro";

interface Review {
  authorAttribution: {
    displayName: string;
    uri: string;
    photoUri: string;
  };
  rating: number;
  text: {
    text: string;
  };
  publishTime: string;
}

let reviews: Review[] = [];
let error = false;

try {
  const response = await fetch(`${Astro.url.origin}/api/google`);
  
  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }
  
  const data = await response.json();
  
  if (data.error) {
    throw new Error(data.error);
  }
  
  reviews = data.reviews || [];
} catch (err) {
  console.error('Error fetching reviews:', err);
  error = true;
}

console.log(reviews);
---

{
  reviews.map(r => (
    <div>
      <p>{r.rating}</p>
    </div>
  ))
}
#

I was able to find out post from @royal storm , that this in the wrangler config fixes it: "disable_nodejs_process_v2"

so hopefully it'll work now, thank you

#

yup all fixed...