Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nuxt server/api files not found #221

Closed
EntertainmentPortal opened this issue Sep 24, 2024 · 12 comments
Closed

Nuxt server/api files not found #221

EntertainmentPortal opened this issue Sep 24, 2024 · 12 comments
Labels
bug Something isn't working

Comments

@EntertainmentPortal
Copy link

Reproduction

Additional Details

nuxt.config:

import { repositoryName, apiEndpoint } from "./slicemachine.config.json";

export default defineNuxtConfig({
  app: {
    head: {
      title: "---",
      htmlAttrs: {
        lang: "en",
      },
      meta: [
        { charset: "utf-8" },
        { name: "viewport", content: "width=device-width, initial-scale=1" },
        { hid: "description", name: "description", content: "" },
        { name: "format-detection", content: "telephone=no" },
      ],
      link: [{ rel: "icon", type: "image/x-icon", href: "/favicon.ico" }],
    },
  },

  compatibilityDate: "2024-09-16",

  css: ["~/assets/css/main.css"],

  dayjs: {
    locales: ["nl"],
    plugins: [
      "relativeTime",
      "utc",
      "timezone",
      "isSameOrBefore",
      "isSameOrAfter",
    ],
    defaultLocale: "nl",
    defaultTimezone: "Europe/Amsterdam",
  },

  devtools: { enabled: false },

  modules: [
    "@nuxtjs/prismic",
    "nuxt-icon",
    "@nuxtjs/google-fonts",
    "dayjs-nuxt",
    "nuxt-csurf",
    "nuxt-primevue",
    "nuxt-snackbar",
    "@pinia/nuxt",
    "@vite-pwa/nuxt",
  ],

  nitro: {
    preset: "vercel-static",
  },

  plugins: [{ src: "~/plugins/service-worker.client.js", mode: "client" }],

  postcss: {
    plugins: {
      tailwindcss: {},
      autoprefixer: {},
    },
  },

  primevue: {
    config: {
      ripple: false,
    },
    components: {
      include: "*",
    },
    directives: {
      include: "*",
    },
    importPT: { as: "PrimeVuePreset", from: "@/assets/js/primevue.js" },
    options: {
      ripple: false,
    },
    cssLayerOrder: "tailwind-base, primevue, tailwind-utilities",
  },

  prismic: {
    endpoint: apiEndpoint || repositoryName,
    preview: false,
    clientConfig: {
      accessToken: process.env.PRISMIC_CLIENT_SECRET,
      routes: [
        {
          type: "page",
          path: "/:uid",
        },
        {
          type: "privacy_policy",
          path: "/privacy-policy",
        },
      ],
    },
  },

  pwa: {
    manifest: {
      name: "---",
      short_name: "---",
      description:
        "---",
      icons: [
        {
          src: "icon.png",
          sizes: "512x512",
          type: "image/png",
        },
        {
          src: "icon.png",
          sizes: "512x512",
          type: "image/png",
        },
      ],
      lang: "nl",
      background_color: "#031221",
      theme_color: "#ffffff",
    },
    workbox: {
      navigateFallback: "/",
      globPatterns: ["**/*.{js,css,html,png,svg,ico}"],
      maximumFileSizeToCacheInBytes: 5000000,
    },
  },

  router: {
    options: {
      scrollBehaviorType: "smooth",
    },
  },

  snackbar: {
    top: true,
    duration: 5000,
  },

  ssr: true,

  target: "static",
});

package.json:

{
  "name": "nuxt-starter-prismic-minimal",
  "version": "0.0.0",
  "private": true,
  "license": "Apache-2.0",
  "author": "Prismic <contact@prismic.io> (https://prismic.io)",
  "scripts": {
    "dev": "concurrently \"npm:nuxt:dev\" \"npm:slicemachine\" --names \"nuxt,slicemachine\" --prefix-colors green,magenta",
    "nuxt:dev": "nuxt dev",
    "build": "nuxt build",
    "generate": "nuxt generate",
    "preview": "nuxt preview",
    "postinstall": "prisma generate && nuxt prepare",
    "slicemachine": "start-slicemachine",
    "lint": "eslint ."
  },
  "devDependencies": {
    "@nuxt/devtools": "^1.1.4",
    "@nuxt/eslint-config": "^0.2.0",
    "@nuxtjs/prismic": "^3.4.1",
    "@slicemachine/adapter-nuxt": "^0.3.42",
    "autoprefixer": "^10.4.19",
    "concurrently": "^8.2.2",
    "eslint": "^8.57.0",
    "nuxt": "^3.11.1",
    "nuxt-primevue": "^3.0.0",
    "postcss": "^8.4.39",
    "slice-machine-ui": "^2.2.1",
    "tailwindcss": "^3.4.6"
  },
  "dependencies": {
    "@mapbox/polyline": "^1.2.1",
    "@nuxtjs/google-fonts": "^3.2.0",
    "@pinia/nuxt": "^0.5.3",
    "@prisma/client": "^5.19.1",
    "@sendgrid/mail": "^7.7.0",
    "@vite-pwa/nuxt": "^0.10.5",
    "dayjs-nuxt": "^2.1.11",
    "nuxt-csurf": "^1.6.2",
    "nuxt-icon": "^0.5.0",
    "nuxt-snackbar": "^1.1.2",
    "ol": "^10.2.0",
    "pinia": "^2.2.1",
    "primevue": "^3.53.0",
    "prisma": "^5.19.1",
    "tailwindcss-ripple": "^0.7.1"
  }
}

Steps to reproduce

Followed the install documentation on prismic with the Nuxt preset.
I have several functions inside /server/api. Some of them are fetched from inside the store. These are some of the involved files:

store/index.js:

actions: {
    async prefetch() {
      const repoName = "---";
      const client = prismic.createClient(repoName);
      try {
        await client.getAllByType("instellingen").then((response) => {
          this.navbar = {
            logo: response[0].data.navbarlogo,
            navbarTitleTop: response[0].data.navbarTitleTop,
            navbarTitleBottom: response[0].data.navbarTitleBottom,
            account_label: response[0].data.account_label,
            menu_label: response[0].data.menu_label,
            hoofdmenu: response[0].data.hoofdmenu,
          };

          this.footer = {
            logo: response[0].data.footerlogo,
            footerTitleTop: response[0].data.footerTitleTop,
            footerTitleBottom: response[0].data.footerTitleBottom,
            contact: response[0].data.contact[0],
            copyright: response[0].data.copyright[0],
          };
        });

        // Get gamedata
        await $fetch("/api/getAllSpellen").then((res) => {
          for (const game of res) {
            this.gamedata = {
              ...this.gamedata,
              [game.spelafkorting]: game,
            };
          }
        });
      } catch (error) {
        console.error(error);
      }
    },
  },

Others are fetched from the frontend (pages or components):

pages/event.vue:

<script setup lang="js">
const fetchGame = async () => {
    try {
      const res = await $csrfFetch("/api/getSpel", {
        method: 'POST',
        body: {
          code: route.params.code
        }
      });
      gamedata.value = res;
    } catch (error) {
      console.error('Error fetching game data:', error);
    }
  };
</script>

What is Expected?

In production, it should fetch data from both Prismic API as from server/api. Prismic API is used to load page data, server/api is used for some functions. Both folders are named 'api', but the foldercontent may differ. Both should be able to work.

What is actually happening?

On localhost, I don't experience any issues. But in production, I get a 404 on api/getSpel. My guess is that it is trying to look for this file from the Prismic API, while it should look inside the server/api folder. Probably a clash because both use /api/**, but again, that is just my guess. Funny detail: it appears that the fetch from the store (index.js) works just fine, but any fetch from the pages / components returns 404.

@EntertainmentPortal EntertainmentPortal added the bug Something isn't working label Sep 24, 2024
@lihbr
Copy link
Collaborator

lihbr commented Sep 24, 2024

Hey @EntertainmentPortal, thanks for contributing and providing the above details!

I find it odd that Nuxt gets confused about which API to query, I don't think it overlaps there 🤔

How are you hosting your website? Maybe Nuxt API (/api/getSpel) doesn't get hosted because you host a full static site without serverless functions perhaps(?)

Otherwise, would you be able to provide a minimal reproduction? Else I'm happy to have a deeper look at your project if you can grant me access to it/share a zip.

@lihbr lihbr added need info Further information is requested need repro A reproduction is needed to further troubleshoot the issue labels Sep 24, 2024
@EntertainmentPortal
Copy link
Author

Hey @lihbr, thank you for the quick reply.

The project's hosted on Vercel. I don't think /api/getSpel isn't hosted, because other functions in that folder that are loaded from the store work fine.

I've added you into the project. Thanks!

@lihbr
Copy link
Collaborator

lihbr commented Sep 24, 2024

Thanks! I'll try to have a look by the end of the day ☺️

@lihbr
Copy link
Collaborator

lihbr commented Sep 24, 2024

OK, I had a look at your codebase, thanks for granting me access, I couldn't find anything odd 🤔

Could you double-check if your environment variables are correctly set on Vercel perhaps?

@lihbr lihbr removed need info Further information is requested need repro A reproduction is needed to further troubleshoot the issue labels Sep 24, 2024
@EntertainmentPortal
Copy link
Author

@lihbr All 6 env are there as they should. This is not the problem. When checking the network tab I learned that Prismic is initiating the call to the api file. (see tab 'initiator')

image

While Prismic shouldn't have anything to do with this file, as it is set in a Vue lifecycle hook. It appears Prismic's interfering with the call after all.

@lihbr
Copy link
Collaborator

lihbr commented Sep 25, 2024

Oh, OK! I'm pretty sure that's unrelated, the toolbar does augment the global fetch just to be able to listen to calls going to Prismic (which isn't ideal I agree and we want to move away from that, but it's really just listening, not tampering)

With that, I believe the issue might be related to something else than Prismic? Maybe we can try confirming that by disabling the Prismic toolbar/preview temporarily by setting preview: false in Nuxt config for prismic? Then you can check again and see if you're able to reproduce the issue without Prismic toolbar.


Trying to think of other things to check for: are you able to see any logs from your function being called on Vercel to try to understand what's going on there? Weirdly, it returns a 404 but according to your code it never throws nor returns so I believe it should be an empty 200 upon success(?)

@EntertainmentPortal
Copy link
Author

I'll check in a minute. The preview: false is already there for a while, as it was causing build errors in Vercel.

@lihbr
Copy link
Collaborator

lihbr commented Sep 25, 2024

OK my bad, to disable the toolbar also use toolbar: false 🙏

@EntertainmentPortal
Copy link
Author

Hmm, still the same result. I also tried disabling the csurf, but this didn't do anything, still 404.

I see that Vercel is not logging anything, regardless the page I visit. You would say we could expect at least the 404 there, wouldn't we?

@lihbr
Copy link
Collaborator

lihbr commented Sep 25, 2024

From my understanding, the 404 is weird because according to your code no 404 could be the result of your handler for getSpel.

My guess is that this endpoint is not available in your production environment somehow. Since the /event/[code] pages don't rely on Prismic or the store at all, I guess you could even try to disable the Prismic module and see if it's reproducible in production.

But yeah, I don't understand why your Nuxt server endpoint is not behaving as in development in Production 🤔

Any chance you could try with your Nitro preset set to vercel? https://github.com/JeffreyVanZwam/ImmerlooTour-Prismic/blob/main/nuxt.config.ts#L62
I'm pretty sure vercel-static doesn't support any serverless function: nitrojs/nitro#1073 (comment) which would explain the above.

@EntertainmentPortal
Copy link
Author

Setting the preset (and change NPM run generate to NPM run build) did indeed solve the problem... It somehow makes sense assuming serverless functions aren't supported, but still funny that fetching (to another file but in the same folder) from the store did work.

Gonna click-around to see if I encounter any other problems now, but for now the problem seems te be solved. Thank you for your patience, help and quick responses! Appreciate it!

@lihbr
Copy link
Collaborator

lihbr commented Sep 25, 2024

You welcome, I'll close the issue for now but feel free to reopen it if anything!

@lihbr lihbr closed this as completed Sep 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants