재우니의 블로그

GITHUB 의 NOTION 을 웹페이지 랜더링해 주는 오픈소스

 

NOTION 을 웹페이지 랜더링 해주는 무료 오픈 소스 사이트를 소개해 줍니다.

Start Kit 를 소개해주며, 이는 react 언어로 구성되어 있습니다.

 

 

https://blog.silentsoft.org/archives/193

 

oopy.io, super.so 대체제를 찾아서 (feat. Notion X)

왜 노션은 다크 모드를 지원하지 않을까

blog.silentsoft.org

Starter Kit

 

GitHub - transitive-bullshit/nextjs-notion-starter-kit: Deploy your own Notion-powered website in minutes with Next.js and Verce

Deploy your own Notion-powered website in minutes with Next.js and Vercel. - GitHub - transitive-bullshit/nextjs-notion-starter-kit: Deploy your own Notion-powered website in minutes with Next.js a...

github.com

 

이를 사용하기 위해서는 root notion page 의 아이디를 알아야 하며, 공개할 노션의 페이지를 공개로 하고나서 주소를 복사하면 아래와 같은 주소를 얻을 수 있습니다. 

 

https://www.notion.so/univ/bcc618d5bdf64644886502fb7ed6102e?pvs=4

와 같은 형태를 지닌 사이트 주소를 얻게 되면, 이는 웹사이트 화면에 보여줄 노션의 페이지 아이디가 바로 붉은색으로 표기된 주소입니다. site.config.ts 에서 수정해 주면 완료된 사항입니다.

 

실행은 아래 구문으로 실행했으며,. 설치 버전 충돌로 잘 안되서 강제로 설치하도록 했습니다.

 

npm install --force
npm run dev

 

 


노션 API 활용하기

 

이젠 노션 api 를 활용하여 특정 형태 부분을 json 형태로 가져와서 커스텀 하는 부분을 설명할 예정입니다.

 

POST 이며, databases/{{아이디}}/query 라는 형태를 가지고 있고, header 로 파라미터를 3개 정도 전송한다. bearer 인증 값, 노션 최신버전 날짜, 전송형식은 json 을 의미합니다.

 

curl --location --request POST 'https://api.notion.com/v1/databases/fb2616ee887e40000000002453b0/query' \
--header 'Authorization: Bearer secret_6w000000000000000oMBclfQO5phcNmg' \
--header 'Notion-Version: 2022-06-28' \
--header 'Content-Type: application/json' \
--header 'Cookie: __cf_bm=mxhttHWnyzjGyPZRadGcpk1fISxSQFefo_QeMjVlnvE-1688362767-0-AWt4j/2UsnLOf6LRl8H62jAxnxtf1PzVDQyxatnugYcjD2jU4MDRS0fibo5L59Y8JGmw7RfjrKFtAh5D/3Wmnew='

 

 

여기서 private api 통합 비밀키 값이 bearer 값입니다.  (https://www.notion.so/my-integrations)

 

 

생성한 api 통합계정을 통해, 원하는 노션에 연결을 해줍니다. 만들어 준, luckycloud 라는 것을 연결합니다.

원하는 테이블의 "보기 링크 복사" 를 통해 주소를 얻습니다.

 

https://www.notion.so/univ/ fb2616ee887e4be38b24a6eb8a2453b0?v=b0c5aecf3e304527849970fdeed0f324&pvs=4
여기서 붉은색으로 보이는 부분의 값을 databases/{{아이디}}/query 에서 {{아이디}} 에 기재합니다.

 

이제 postman 으로 호출하면 json 형태로 데이터를 제공해 줍니다.

 

 

보면 정말 다양한 값을 제공해 주며, 여기서 properties 내부에 자료를 기반으로 파싱하면 된다. json 을 기반으로 파싱하여 표형태로 html 형태의 테이블로 보여줍니다.

 

 

 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>JSON to HTML Table</title>
  <style>
    table {
      border-collapse: collapse;
      width: 100%;
    }
    th, td {
      border: 1px solid black;
      padding: 8px;
      text-align: left;
    }
    th {
      background-color: #f2f2f2;
    }
  </style>
</head>
<body>
  <table id="notionTable">
    <thead>
      <tr>
        <th>제목</th>
        <th>읽은 날짜</th>
        <th>Day</th>
        <th>체크</th>
        <th>파일</th>
      </tr>
    </thead>
    <tbody></tbody>
  </table>

  <script>
    const jsonData = {
    "object": "list",
    "results": [
        {
            "object": "page",
            "id": "f1d64c35-f7b5-484d-bcb5-b8dce765c8ca",
            "created_time": "2023-04-18T01:58:00.000Z",
            "last_edited_time": "2023-04-18T01:58:00.000Z",
            "created_by": {
                "object": "user",
                "id": "c6350e93-151d-4fc7-8793-5094914a2f97"
            },
            "last_edited_by": {
                "object": "user",
                "id": "c6350e93-151d-4fc7-8793-5094914a2f97"
            },
            "cover": null,
            "icon": {
                "type": "external",
                "external": {
                    "url": "https://www.notion.so/icons/checkmark_green.svg"
                }
            },
            "parent": {
                "type": "database_id",
                "database_id": "fb2616ee-887e-4be3-8b24-a6eb8a2453b0"
            },
            "archived": false,
            "properties": {
                "Cover": {
                    "id": "%3B%5DbB",
                    "type": "files",
                    "files": [
                        {
                            "name": "https://publy.imgix.net/images/2022/09/13/1663035356_mG6sOu0JyoizCgnR08iCkOYoXLgg1PynfdZiooaq.png?fm=pjpg",
                            "type": "external",
                            "external": {
                                "url": "https://publy.imgix.net/images/2022/09/13/1663035356_mG6sOu0JyoizCgnR08iCkOYoXLgg1PynfdZiooaq.png?fm=pjpg"
                            }
                        }
                    ]
                },
                "읽은 날짜": {
                    "id": "%3Ei~r",
                    "type": "date",
                    "date": {
                        "start": "2022-10-19",
                        "end": null,
                        "time_zone": null
                    }
                },
                "Day ": {
                    "id": "HGUT",
                    "type": "number",
                    "number": 1
                },
                "체크": {
                    "id": "_Esz",
                    "type": "status",
                    "status": {
                        "id": "a8ecae75-1066-4236-b896-6a429e33337c",
                        "name": "읽었어",
                        "color": "green"
                    }
                },
                "제목": {
                    "id": "title",
                    "type": "title",
                    "title": [
                        {
                            "type": "text",
                            "text": {
                                "content": "주먹구구식에서 벗어나 제대로 된 팀 업무 체계 만드는 법",
                                "link": null
                            },
                            "annotations": {
                                "bold": false,
                                "italic": false,
                                "strikethrough": false,
                                "underline": false,
                                "code": false,
                                "color": "default"
                            },
                            "plain_text": "주먹구구식에서 벗어나 제대로 된 팀 업무 체계 만드는 법",
                            "href": null
                        }
                    ]
                }
            },
            "url": "https://www.notion.so/f1d64c35f7b5484dbcb5b8dce765c8ca",
            "public_url": null
        },
        {
            "object": "page",
            "id": "1cce8253-adda-475f-a304-401df16ac096",
            "created_time": "2023-04-18T01:58:00.000Z",
            "last_edited_time": "2023-04-18T01:58:00.000Z",
            "created_by": {
                "object": "user",
                "id": "c6350e93-151d-4fc7-8793-5094914a2f97"
            },
            "last_edited_by": {
                "object": "user",
                "id": "c6350e93-151d-4fc7-8793-5094914a2f97"
            },
            "cover": null,
            "icon": {
                "type": "external",
                "external": {
                    "url": "https://www.notion.so/icons/checkmark_green.svg"
                }
            },
            "parent": {
                "type": "database_id",
                "database_id": "fb2616ee-887e-4be3-8b24-a6eb8a2453b0"
            },
            "archived": false,
            "properties": {
                "Cover": {
                    "id": "%3B%5DbB",
                    "type": "files",
                    "files": [
                        {
                            "name": "https://publy.imgix.net/images/2022/08/31/1661908254_TbAsRgvJRjiKFofXgP15uGpAsHfMQuRI7zQRqyM8.jpeg?fm=pjpg",
                            "type": "external",
                            "external": {
                                "url": "https://publy.imgix.net/images/2022/08/31/1661908254_TbAsRgvJRjiKFofXgP15uGpAsHfMQuRI7zQRqyM8.jpeg?fm=pjpg"
                            }
                        }
                    ]
                },
                "읽은 날짜": {
                    "id": "%3Ei~r",
                    "type": "date",
                    "date": {
                        "start": "2022-10-22",
                        "end": null,
                        "time_zone": null
                    }
                },
                "Day ": {
                    "id": "HGUT",
                    "type": "number",
                    "number": 2
                },
                "체크": {
                    "id": "_Esz",
                    "type": "status",
                    "status": {
                        "id": "a8ecae75-1066-4236-b896-6a429e33337c",
                        "name": "읽었어",
                        "color": "green"
                    }
                },
                "제목": {
                    "id": "title",
                    "type": "title",
                    "title": [
                        {
                            "type": "text",
                            "text": {
                                "content": "갑자기 팀장이 되었다: 첫 50일 동안 해야 할 4가지 일",
                                "link": null
                            },
                            "annotations": {
                                "bold": false,
                                "italic": false,
                                "strikethrough": false,
                                "underline": false,
                                "code": false,
                                "color": "default"
                            },
                            "plain_text": "갑자기 팀장이 되었다: 첫 50일 동안 해야 할 4가지 일",
                            "href": null
                        }
                    ]
                }
            },
            "url": "https://www.notion.so/50-4-1cce8253adda475fa304401df16ac096",
            "public_url": null
        },
        {
            "object": "page",
            "id": "8a980519-9012-4ca9-b071-1edd74873528",
            "created_time": "2023-04-18T01:58:00.000Z",
            "last_edited_time": "2023-04-18T01:58:00.000Z",
            "created_by": {
                "object": "user",
                "id": "c6350e93-151d-4fc7-8793-5094914a2f97"
            },
            "last_edited_by": {
                "object": "user",
                "id": "c6350e93-151d-4fc7-8793-5094914a2f97"
            },
            "cover": null,
            "icon": {
                "type": "external",
                "external": {
                    "url": "https://www.notion.so/icons/checkmark_green.svg"
                }
            },
            "parent": {
                "type": "database_id",
                "database_id": "fb2616ee-887e-4be3-8b24-a6eb8a2453b0"
            },
            "archived": false,
            "properties": {
                "Cover": {
                    "id": "%3B%5DbB",
                    "type": "files",
                    "files": [
                        {
                            "name": "https://publy.imgix.net/images/2022/09/27/1664239964_4mxUa13y4E1mFuYjnAq9MiyDceNrUPrKxf7vAdaR.png?fm=pjpg",
                            "type": "external",
                            "external": {
                                "url": "https://publy.imgix.net/images/2022/09/27/1664239964_4mxUa13y4E1mFuYjnAq9MiyDceNrUPrKxf7vAdaR.png?fm=pjpg"
                            }
                        }
                    ]
                },
                "읽은 날짜": {
                    "id": "%3Ei~r",
                    "type": "date",
                    "date": null
                },
                "Day ": {
                    "id": "HGUT",
                    "type": "number",
                    "number": 7
                },
                "체크": {
                    "id": "_Esz",
                    "type": "status",
                    "status": {
                        "id": "a8ecae75-1066-4236-b896-6a429e33337c",
                        "name": "읽었어",
                        "color": "green"
                    }
                },
                "제목": {
                    "id": "title",
                    "type": "title",
                    "title": [
                        {
                            "type": "text",
                            "text": {
                                "content": "나의 커리어 해방일지: 힘든 직장생활을 견뎌내는 법",
                                "link": null
                            },
                            "annotations": {
                                "bold": false,
                                "italic": false,
                                "strikethrough": false,
                                "underline": false,
                                "code": false,
                                "color": "default"
                            },
                            "plain_text": "나의 커리어 해방일지: 힘든 직장생활을 견뎌내는 법",
                            "href": null
                        }
                    ]
                }
            },
            "url": "https://www.notion.so/8a98051990124ca9b0711edd74873528",
            "public_url": null
        },
        {
            "object": "page",
            "id": "9c12322e-2bac-4554-bcf1-a494a6415621",
            "created_time": "2023-04-18T01:58:00.000Z",
            "last_edited_time": "2023-04-18T01:58:00.000Z",
            "created_by": {
                "object": "user",
                "id": "c6350e93-151d-4fc7-8793-5094914a2f97"
            },
            "last_edited_by": {
                "object": "user",
                "id": "c6350e93-151d-4fc7-8793-5094914a2f97"
            },
            "cover": null,
            "icon": {
                "type": "external",
                "external": {
                    "url": "https://www.notion.so/icons/checkmark_green.svg"
                }
            },
            "parent": {
                "type": "database_id",
                "database_id": "fb2616ee-887e-4be3-8b24-a6eb8a2453b0"
            },
            "archived": false,
            "properties": {
                "Cover": {
                    "id": "%3B%5DbB",
                    "type": "files",
                    "files": [
                        {
                            "name": "https://publy.imgix.net/images/2022/06/29/1656463148_NBaq3ep93smSFhoCBmckLcxKR1DTjpzCwnAGxxAn.png?fm=pjpg",
                            "type": "external",
                            "external": {
                                "url": "https://publy.imgix.net/images/2022/06/29/1656463148_NBaq3ep93smSFhoCBmckLcxKR1DTjpzCwnAGxxAn.png?fm=pjpg"
                            }
                        }
                    ]
                },
                "읽은 날짜": {
                    "id": "%3Ei~r",
                    "type": "date",
                    "date": null
                },
                "Day ": {
                    "id": "HGUT",
                    "type": "number",
                    "number": 4
                },
                "체크": {
                    "id": "_Esz",
                    "type": "status",
                    "status": {
                        "id": "e2c03cd5-abf2-43a7-96e9-46c18d3412f2",
                        "name": "다시 읽을 예정",
                        "color": "purple"
                    }
                },
                "제목": {
                    "id": "title",
                    "type": "title",
                    "title": [
                        {
                            "type": "text",
                            "text": {
                                "content": "회의록 NO! 팀장의 부재에도 굴러가게 만드는 ‘작은 성공 회의’ 세팅법",
                                "link": null
                            },
                            "annotations": {
                                "bold": false,
                                "italic": false,
                                "strikethrough": false,
                                "underline": false,
                                "code": false,
                                "color": "default"
                            },
                            "plain_text": "회의록 NO! 팀장의 부재에도 굴러가게 만드는 ‘작은 성공 회의’ 세팅법",
                            "href": null
                        }
                    ]
                }
            },
            "url": "https://www.notion.so/NO-9c12322e2bac4554bcf1a494a6415621",
            "public_url": null
        },
        {
            "object": "page",
            "id": "a366f4aa-4c20-4936-bc25-524e8b442208",
            "created_time": "2023-04-18T01:58:00.000Z",
            "last_edited_time": "2023-04-18T01:58:00.000Z",
            "created_by": {
                "object": "user",
                "id": "c6350e93-151d-4fc7-8793-5094914a2f97"
            },
            "last_edited_by": {
                "object": "user",
                "id": "c6350e93-151d-4fc7-8793-5094914a2f97"
            },
            "cover": null,
            "icon": {
                "type": "external",
                "external": {
                    "url": "https://www.notion.so/icons/checkmark_green.svg"
                }
            },
            "parent": {
                "type": "database_id",
                "database_id": "fb2616ee-887e-4be3-8b24-a6eb8a2453b0"
            },
            "archived": false,
            "properties": {
                "Cover": {
                    "id": "%3B%5DbB",
                    "type": "files",
                    "files": [
                        {
                            "name": "https://publy.imgix.net/images/2022/10/17/1665968296_jYgU77W9ZCOc6gYS1eEQ49kc4uU9ASo6Kj5DGWtg.png?fm=pjpg",
                            "type": "external",
                            "external": {
                                "url": "https://publy.imgix.net/images/2022/10/17/1665968296_jYgU77W9ZCOc6gYS1eEQ49kc4uU9ASo6Kj5DGWtg.png?fm=pjpg"
                            }
                        }
                    ]
                },
                "읽은 날짜": {
                    "id": "%3Ei~r",
                    "type": "date",
                    "date": null
                },
                "Day ": {
                    "id": "HGUT",
                    "type": "number",
                    "number": 6
                },
                "체크": {
                    "id": "_Esz",
                    "type": "status",
                    "status": {
                        "id": "7a1f2104-f00b-4e78-9a59-8ffc59d817a7",
                        "name": "읽는 중",
                        "color": "blue"
                    }
                },
                "제목": {
                    "id": "title",
                    "type": "title",
                    "title": [
                        {
                            "type": "text",
                            "text": {
                                "content": "위기를 기회로 만드는 리더의 3단계 리스크 관리법",
                                "link": null
                            },
                            "annotations": {
                                "bold": false,
                                "italic": false,
                                "strikethrough": false,
                                "underline": false,
                                "code": false,
                                "color": "default"
                            },
                            "plain_text": "위기를 기회로 만드는 리더의 3단계 리스크 관리법",
                            "href": null
                        }
                    ]
                }
            },
            "url": "https://www.notion.so/3-a366f4aa4c204936bc25524e8b442208",
            "public_url": null
        },
        {
            "object": "page",
            "id": "ef6071a2-0687-4097-9dc6-afe7a84bb25a",
            "created_time": "2023-04-18T01:58:00.000Z",
            "last_edited_time": "2023-04-18T01:58:00.000Z",
            "created_by": {
                "object": "user",
                "id": "c6350e93-151d-4fc7-8793-5094914a2f97"
            },
            "last_edited_by": {
                "object": "user",
                "id": "c6350e93-151d-4fc7-8793-5094914a2f97"
            },
            "cover": null,
            "icon": {
                "type": "external",
                "external": {
                    "url": "https://www.notion.so/icons/checkmark_green.svg"
                }
            },
            "parent": {
                "type": "database_id",
                "database_id": "fb2616ee-887e-4be3-8b24-a6eb8a2453b0"
            },
            "archived": false,
            "properties": {
                "Cover": {
                    "id": "%3B%5DbB",
                    "type": "files",
                    "files": [
                        {
                            "name": "https://publy.imgix.net/images/2022/05/18/1652838461_TqGf8waFGfG2ddHFxN5kO2yiVdrLkRcSSx93nc7z.png?fm=pjpg",
                            "type": "external",
                            "external": {
                                "url": "https://publy.imgix.net/images/2022/05/18/1652838461_TqGf8waFGfG2ddHFxN5kO2yiVdrLkRcSSx93nc7z.png?fm=pjpg"
                            }
                        }
                    ]
                },
                "읽은 날짜": {
                    "id": "%3Ei~r",
                    "type": "date",
                    "date": null
                },
                "Day ": {
                    "id": "HGUT",
                    "type": "number",
                    "number": 3
                },
                "체크": {
                    "id": "_Esz",
                    "type": "status",
                    "status": {
                        "id": "a8ecae75-1066-4236-b896-6a429e33337c",
                        "name": "읽었어",
                        "color": "green"
                    }
                },
                "제목": {
                    "id": "title",
                    "type": "title",
                    "title": [
                        {
                            "type": "text",
                            "text": {
                                "content": "팀 효율을 높이는 팀장은 매뉴얼을 ‘이렇게’ 만든다 (린 매뉴얼)",
                                "link": null
                            },
                            "annotations": {
                                "bold": false,
                                "italic": false,
                                "strikethrough": false,
                                "underline": false,
                                "code": false,
                                "color": "default"
                            },
                            "plain_text": "팀 효율을 높이는 팀장은 매뉴얼을 ‘이렇게’ 만든다 (린 매뉴얼)",
                            "href": null
                        }
                    ]
                }
            },
            "url": "https://www.notion.so/ef6071a2068740979dc6afe7a84bb25a",
            "public_url": null
        },
        {
            "object": "page",
            "id": "04caeacc-8f85-4fce-975e-9a699c590ef5",
            "created_time": "2023-04-18T01:58:00.000Z",
            "last_edited_time": "2023-04-18T01:58:00.000Z",
            "created_by": {
                "object": "user",
                "id": "c6350e93-151d-4fc7-8793-5094914a2f97"
            },
            "last_edited_by": {
                "object": "user",
                "id": "c6350e93-151d-4fc7-8793-5094914a2f97"
            },
            "cover": null,
            "icon": {
                "type": "external",
                "external": {
                    "url": "https://www.notion.so/icons/checkmark_green.svg"
                }
            },
            "parent": {
                "type": "database_id",
                "database_id": "fb2616ee-887e-4be3-8b24-a6eb8a2453b0"
            },
            "archived": false,
            "properties": {
                "Cover": {
                    "id": "%3B%5DbB",
                    "type": "files",
                    "files": [
                        {
                            "name": "https://publy.imgix.net/images/2022/05/12/1652319762_TkxNBgKyjL2aTErcmfq0gqwXEcH2FujizybCzmYJ.jpeg?fm=pjpg",
                            "type": "external",
                            "external": {
                                "url": "https://publy.imgix.net/images/2022/05/12/1652319762_TkxNBgKyjL2aTErcmfq0gqwXEcH2FujizybCzmYJ.jpeg?fm=pjpg"
                            }
                        }
                    ]
                },
                "읽은 날짜": {
                    "id": "%3Ei~r",
                    "type": "date",
                    "date": null
                },
                "Day ": {
                    "id": "HGUT",
                    "type": "number",
                    "number": 5
                },
                "체크": {
                    "id": "_Esz",
                    "type": "status",
                    "status": {
                        "id": "e2c03cd5-abf2-43a7-96e9-46c18d3412f2",
                        "name": "다시 읽을 예정",
                        "color": "purple"
                    }
                },
                "제목": {
                    "id": "title",
                    "type": "title",
                    "title": [
                        {
                            "type": "text",
                            "text": {
                                "content": "프로젝트 단위로 일한다면? 빠르게 성과내는 팀 세팅법",
                                "link": null
                            },
                            "annotations": {
                                "bold": false,
                                "italic": false,
                                "strikethrough": false,
                                "underline": false,
                                "code": false,
                                "color": "default"
                            },
                            "plain_text": "프로젝트 단위로 일한다면? 빠르게 성과내는 팀 세팅법",
                            "href": null
                        }
                    ]
                }
            },
            "url": "https://www.notion.so/04caeacc8f854fce975e9a699c590ef5",
            "public_url": null
        }
    ],
    "next_cursor": null,
    "has_more": false,
    "type": "page",
    "page": {},
    "developer_survey": "https://notionup.typeform.com/to/bllBsoI4?utm_source=postman"
};

    const tableBody = document.querySelector('#notionTable tbody');

    jsonData.results.forEach(result => {
      const title = result.properties.제목.title[0].plain_text;
      const date = result.properties['읽은 날짜'].date?.start;
      const day = result.properties['Day '].number;
      const check = result.properties.체크.status.name;
      const file = result.properties.Cover.files[0].name;

      const newRow = tableBody.insertRow();
      newRow.innerHTML = `
      <td>${title}</td>
      <td>${date || ''}</td>
      <td>${day}</td>
      <td>${check}</td>
      <td><img src='${file}' width="100px"></td>
      `;
    });
  </script>
</body>
</html>

 

표 형태를 기반으로 파싱해서 동적으로 html 의 표를 그린 내용을 캡쳐 했습니다.

 

html.html
0.03MB