skip to Main Content

I have a Next.js app with the following structure:

.
├── next.config.js
└── src /
    └── app/
        ├── page.tsx
        └── getYoutubeTranscript/
            └── getYoutubeTranscript.tsx

next.config.js has the following policy defined:

// @ts-check
 
/** @type {import('next').NextConfig} */
const nextConfig = {
    async headers() {
        return [
            {
                // matching all API routes
                source: "/api/:path*",
                headers: [
                    { key: "Access-Control-Allow-Credentials", value: "true" },
                    { key: "Access-Control-Allow-Origin", value: "*" }, //http://localhost:3000
                    { key: "Access-Control-Allow-Methods", value: "GET,DELETE,PATCH,POST,PUT" },
                    { key: "Access-Control-Allow-Headers", value: "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" },
                ]
            }
        ]
    }
}

module.exports = nextConfig

page.tsx is a client component that uses the getYoutubeTranscript server component to fetch a Youtube transcript. But when this code executes I get the client-side error:

Access to fetch at 'https://www.youtube.com/watch?v=<ID>' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Looks like I misconfigured CORS in next.config.js — any tips here to further diagnose?


Update #1: I don’t see a Host listed in the Request Headers of my call from Developer Console? This answer implies when Host != Origin that causes the error

enter image description here

Update #2: Here are the Response Headers (two images):

enter image description here
enter image description here

2

Answers


  1. Chosen as BEST ANSWER

  2. I think you have misunderstood CORS. You try to fetch some youtube URLs from localhost (with xhr I assume) which YOUTUBE doesn’t allow with its CORS. Changing your own API CORS will allow other sites to fetch from your API

    I also have a couple of notes on the question/update:

    1. When asked what OPTIONS returns, we need the response, not the request
    2. You added some CORS config to an /api/ path but I can’t see any in your screenshot of the structure.

    Now, guessing a bit here since I can’t be sure of what happens here, if you want to fetch a youtube video in your NextJS app, you need to fetch it FROM an API or a server component.

    Anyways… You say that the getYoutubeTranscript is a server component and it fetches from youtube so I also think there is an error in the definition here somewhere since, if it was, you wouldn’t have any CORS issues. I guess a missing 'use server' somewhere…

    My 2 cents on an alternative: As a rule, I never change my page.tsx to client components so that I can always fetch the necessary data there.

    Final note: As far as I know, you are not allowed to fetch youtube.com/watch URLs only the embedded ones. Youtube videos will actually not play if not on their domains. But I may be mistaken here…

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search