1

Today I faced with an issue where any solution found in interned could not handle it.

I am trying to create a blog app using amazing Notion.so note-taking app. Of course, for this stuff I need their API.

Before implementing in React code I tested everything in Insomnia (postman like app). Everything worked smoothly.

When I started to implement first request in react-redux... boom everything is ruined.

This is where request is made:

export const notionApi = createApi({
  reducerPath: "notionApi",
  baseQuery: fetchBaseQuery({
    baseUrl: "https://api.notion.com/v1",
    prepareHeaders: headers => {
      headers.set("Authorization", process.env.REACT_APP_NOTION_SECRET);
      headers.set("Notion-Version", " 2022-02-22");
      return headers;
    }
  }),
  endpoints: builder => ({
    getMenu: builder.query({
      query: id => `/blocks/${id}/children`
    })
  })
});

export const { useGetMenuQuery } = notionApi;

This is in browser:

Access to fetch at 'https://api.notion.com/v1/blocks/c5886e5e15d04d4bb8112bafcec8475b/children' from 
origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight 
request doesn't pass access control check: 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.

Believe or not, I tried everything: Cors Chrome App to imitate, CRA proxy to in package.json, express sever to imitate proxy and 5 hours of desperate search.

  • Does https://github.com/makenotion/notion-sdk-js/issues/96#issuecomment-870581720 help? – Shahriar Oct 15 '22 at 19:39
  • @Shahriar after your comment I tried to solve this with Cloudfare Worker. Again the cors problem still exists. – Elvin Huseynov Oct 16 '22 at 03:52
  • I searched for the problem, and many said Notion doesn't support CORS yet. What you need to do is to call the API on server side, and not client side. Maybe with Express.js, or some kind of middleware. – Shahriar Oct 16 '22 at 07:02

1 Answers1

0

First thanks to Shahriar for the valuable tip in comment. The only variant to execute Notion's API is proxying it so far. Here is how I made Notion.so API work in browser.

First I started an Express server.

// server.js

const app = express();
const server = http.createServer(app);

app.use(express.json());
app.use(cors());

app.get('/getmenu', async (req, res) => {
  const data = await NotionApi('uuid');
  res.status(200).json(data);
});


const PORT = process.env.PORT || 5000;
server.listen(PORT, console.log(`Server started @ ${PORT}`));

Using axios I created function to make calls to Notion API:

// utils/NotionApi.js

require('dotenv').config();
const axios = require('axios');

async function NotionApi(id) {
  return await axios
    .get(`https://api.notion.com/v1/blocks/${id}/children`, {
      headers: {
        Authorization: `Bearer ${process.env.NOTION_SECRET}`,
        'Notion-Version': ' 2022-02-22',
      },
    })
    .then(async (res) => {
      return res.data;
    })
    .catch((err) => {
      NotionApi = undefined;
      console.log(err);
    });
}

module.exports = NotionApi;

Then I deployed this beauty to Heroku and Voilà!

Project url where Notion needed: https://jsadvanced.github.io/

  • Yes, this is the entire point of CORS on a server side endpoint, so that you **can't** just request it from a browser. Never put API or secret keys in your client-side app, it's a horrible idea. – NeuronButter Nov 09 '22 at 08:43