


[Laman Web Peribadi] Cara Mengintegrasikan Pangkalan Data Notion dalam Seterusnya
Untuk menyepadukan pangkalan data Notion ke dalam projek Next.js, anda boleh menggunakan Notion sebagai sistem pengurusan kandungan (CMS) dan memaparkan kandungannya di tapak web anda. Di bawah ialah panduan langkah demi langkah yang mudah untuk membantu anda menyepadukan pangkalan data Notion ke dalam Next.js.
Persediaan Asas
Dapatkan Kunci API Notion dan ID Pangkalan Data
- Dapatkan Kunci API Notion: Pergi ke Portal Pembangun Notion dan buat penyepaduan baharu. Setelah dibuat, anda akan menerima kunci API.
- Dapatkan ID Pangkalan Data: Navigasi ke pangkalan data Notion yang anda mahu integrasikan, dan salin URL halaman pangkalan data. ID pangkalan data ialah rentetan aksara antara https://www.notion.so/ dan ?v= dalam URL.
还不清楚的可以看上篇文章:【01.【个人网站】如何使用Notion作为数据库倨数据库倨进行
Menggunakan SDK Rasmi
Langkah 1: Pasang Ketergantungan
Pertama, anda perlu memasang SDK rasmi Notion, @notionhq/client, untuk berkomunikasi dengan API Notion. Anda boleh memasangnya menggunakan npm atau yarn:
npm install @notionhq/client # or yarn add @notionhq/client
Langkah 2: Sediakan Klien Notion
Buat fail lib/notion.js dalam direktori akar projek Next.js anda dan konfigurasikan klien Notion seperti berikut:
// lib/notion.js import { Client } from '@notionhq/client'; const notion = new Client({ auth: process.env.NOTION_API_KEY, }); export const getDatabase = async (databaseId) => { const response = await notion.databases.query({ database_id: databaseId }); return response.results; };Pastikan menyimpan kunci API Notion anda dalam pembolehubah persekitaran NOTION_API_KEY.(.env.local)
NOTION_API_KEY=your_secret_api_key
Langkah 3: Ambil Kandungan Pangkalan Data
Dalam halaman Next.js anda, anda boleh menggunakan getStaticProps atau getServerSideProps untuk mengambil kandungan daripada pangkalan data Notion.
// pages/index.js import { getDatabase } from '../lib/notion'; export const getStaticProps = async () => { const databaseId = process.env.NOTION_DATABASE_ID; const posts = await getDatabase(databaseId); return { props: { posts, }, revalidate: 1, // ISR (Incremental Static Regeneration) }; }; export default function Home({ posts }) { return ( <div> <h1 id="My-Notion-Blog">My Notion Blog</h1> <ul> {posts.map((post) => ( <li key="{post.id}"> {post.properties.Name.title[0].plain_text} </li> ))} </ul> </div> ); }Pastikan anda mempunyai ID pangkalan data Notion anda disimpan dalam NOTION_DATABASE_ID sebagai pembolehubah persekitaran.
NOTION_DATABASE_ID=your_database_id
Langkah 4: Penerapan dan Pengesahan
Akhir sekali, gunakan projek Next.js anda ke Vercel atau platform lain dan sahkan bahawa anda berjaya mengambil dan memaparkan data daripada pangkalan data Notion.
Petua Tambahan
- Anda boleh memaparkan sifat halaman Notion yang berbeza (seperti Nama, Teg, Tarikh, dll.) pada halaman anda.
- Pertimbangkan untuk menggunakan getServerSideProps untuk mengambil data pada setiap permintaan atau gunakan getStaticProps dengan ISR (Incremental Static Regeneration) untuk mengoptimumkan prestasi.
Menggunakan Notion API dengan URL Berbalut
Akhir sekali, saya akhirnya menggunakan kaedah ini untuk kemudahan apabila menyepadukan dengan komponen react-notion-x.Pastikan anda menambah ID Pangkalan Data Notion dan Kunci API Notion anda pada fail .env.local:
NOTION_DATABASE_ID=your_database_id NOTION_API_KEY=your_secret_api_keyLangkah 1: Pasang kebergantungan yang diperlukan
Mula-mula, pasang kebergantungan yang diperlukan seperti notion-types, notion-utils dan perlu mengendalikan permintaan kepada Notion API.
npm install notion-types notion-utils got p-map
Langkah 2: Buat fail untuk merangkum interaksi Notion API
Dalam projek Next.js anda, buat fail, contohnya, lib/NotionAPI.ts, yang akan merangkum interaksi dengan API Notion. Fail ini akan mengandungi kaedah untuk memanggil titik akhir Notion API untuk mengambil data daripada halaman dan koleksi.
// lib/NotionAPI.ts import * as notion from "notion-types"; import got, { OptionsOfJSONResponseBody } from "got"; import { getBlockCollectionId, getPageContentBlockIds, parsePageId, uuidToId, } from "notion-utils"; import pMap from "p-map"; // 定义权限记录接口 export interface SignedUrlRequest { permissionRecord: PermissionRecord; url: string; } export interface PermissionRecord { table: string; id: notion.ID; } export interface SignedUrlResponse { signedUrls: string[]; } // 定义NotionAPI类 export class NotionAPI { private readonly _apiBaseUrl: string; private readonly _authToken?: string; private readonly _activeUser?: string; private readonly _userTimeZone: string; constructor({ apiBaseUrl = "<https:>", authToken, activeUser, userTimeZone = "America/New_York", }: { apiBaseUrl?: string; authToken?: string; userLocale?: string; userTimeZone?: string; activeUser?: string; } = {}) { this._apiBaseUrl = apiBaseUrl; this._authToken = authToken; this._activeUser = activeUser; this._userTimeZone = userTimeZone; } // 获取页面内容 public async getPage( pageId: string, { concurrency = 3, fetchMissingBlocks = true, fetchCollections = true, signFileUrls = true, chunkLimit = 100, chunkNumber = 0, gotOptions, }: { concurrency?: number; fetchMissingBlocks?: boolean; fetchCollections?: boolean; signFileUrls?: boolean; chunkLimit?: number; chunkNumber?: number; gotOptions?: OptionsOfJSONResponseBody; } = {} ): Promise<notion.extendedrecordmap> { const page = await this.getPageRaw(pageId, { chunkLimit, chunkNumber, gotOptions, }); const recordMap = page?.recordMap as notion.ExtendedRecordMap; if (!recordMap?.block) { throw new Error(`Notion page not found "${uuidToId(pageId)}"`); } recordMap.collection = recordMap.collection ?? {}; recordMap.collection_view = recordMap.collection_view ?? {}; recordMap.notion_user = recordMap.notion_user ?? {}; recordMap.collection_query = {}; recordMap.signed_urls = {}; if (fetchMissingBlocks) { while (true) { const pendingBlockIds = getPageContentBlockIds(recordMap).filter( (id) => !recordMap.block[id] ); if (!pendingBlockIds.length) { break; } const newBlocks = await this.getBlocks( pendingBlockIds, gotOptions ).then((res) => res.recordMap.block); recordMap.block = { ...recordMap.block, ...newBlocks }; } } const contentBlockIds = getPageContentBlockIds(recordMap); if (fetchCollections) { const allCollectionInstances: Array = contentBlockIds.flatMap((blockId) => { const block = recordMap.block[blockId].value; const collectionId = block && (block.type === "collection_view" || block.type === "collection_view_page") && getBlockCollectionId(block, recordMap); if (collectionId) { return block.view_ids?.map((collectionViewId) => ({ collectionId, collectionViewId, })); } else { return []; } }); await pMap( allCollectionInstances, async (collectionInstance) => { const { collectionId, collectionViewId } = collectionInstance; const collectionView = recordMap.collection_view[collectionViewId]?.value; try { const collectionData = await this.getCollectionData( collectionId, collectionViewId, collectionView, { gotOptions, } ); recordMap.block = { ...recordMap.block, ...collectionData.recordMap.block, }; recordMap.collection = { ...recordMap.collection, ...collectionData.recordMap.collection, }; recordMap.collection_view = { ...recordMap.collection_view, ...collectionData.recordMap.collection_view, }; recordMap.notion_user = { ...recordMap.notion_user, ...collectionData.recordMap.notion_user, }; recordMap.collection_query![collectionId] = { ...recordMap.collection_query![collectionId], [collectionViewId]: (collectionData.result as any) ?.reducerResults, }; } catch (err: any) { console.warn( "NotionAPI collectionQuery error", pageId, err.message ); } }, { concurrency, } ); } if (signFileUrls) { await this.addSignedUrls({ recordMap, contentBlockIds, gotOptions }); } return recordMap; } public async addSignedUrls({ recordMap, contentBlockIds, gotOptions = {}, }: { recordMap: notion.ExtendedRecordMap; contentBlockIds?: string[]; gotOptions?: OptionsOfJSONResponseBody; }) { recordMap.signed_urls = {}; if (!contentBlockIds) { contentBlockIds = getPageContentBlockIds(recordMap); } const allFileInstances = contentBlockIds.flatMap((blockId) => { const block = recordMap.block[blockId]?.value; if ( block && (block.type === "pdf" || block.type === "audio" || (block.type === "image" && block.file_ids?.length) || block.type === "video" || block.type === "file" || block.type === "page") ) { const source = block.type === "page" ? block.format?.page_cover : block.properties?.source?.[0]?.[0]; if (source) { if (!source.includes("secure.notion-static.com")) { return []; } return { permissionRecord: { table: "block", id: block.id, }, url: source, }; } } return []; }); if (allFileInstances.length > 0) { try { const { signedUrls } = await this.getSignedFileUrls( allFileInstances, gotOptions ); if (signedUrls.length === allFileInstances.length) { for (let i = 0; i { const parsedPageId = parsePageId(pageId); if (!parsedPageId) { throw new Error(`invalid notion pageId "${pageId}"`); } const body = { pageId: parsedPageId, limit: chunkLimit, chunkNumber: chunkNumber, cursor: { stack: [] }, verticalColumns: false, }; return this.fetch<notion.pagechunk>({ endpoint: "loadPageChunk", body, gotOptions, }); } public async getCollectionData( collectionId: string, collectionViewId: string, collectionView?: any, { limit = 9999, searchQuery = "", userTimeZone = this._userTimeZone, loadContentCover = true, gotOptions, }: { limit?: number; searchQuery?: string; userTimeZone?: string; loadContentCover?: boolean; gotOptions?: OptionsOfJSONResponseBody; } = {} ) { const type = collectionView?.type; const isBoardType = type === "board"; const groupBy = isBoardType ? collectionView?.format?.board_columns_by : collectionView?.format?.collection_group_by; let filters = []; if (collectionView?.format?.property_filters) { filters = collectionView.format?.property_filters.map( (filterObj : any) => ({ property: filterObj?.property, filter: { operator: "and", filters: filterObj?.filter?.filters, }, }) ); } const body = { collection: { id: collectionId, }, collectionView: { id: collectionViewId, }, loader: { type: "reducer", reducers: { collection_group_results: { type: "results", limit, loadContentCover, }, }, userTimeZone, limit, loadContentCover, searchQuery, userLocale: "en", ...(filters.length > 0 ? { filters } : {}), ...(groupBy ? { groupBy, } : {}), }, }; return this.fetch<notion.collectioninstance>({ endpoint: "queryCollection", body, gotOptions, }); } private async fetch<r>({ endpoint, body, gotOptions, }: { endpoint: string; body: unknown; gotOptions?: OptionsOfJSONResponseBody; }) { const url = `${this._apiBaseUrl}/${endpoint}`; const json = true; const method = "POST"; const headers: Record<string string> = { "Content-Type": "application/json", }; if (this._authToken) { headers.cookie = `token_v2=${this._authToken}`; } if (this._activeUser) { headers["x-notion-active-user-header"] = this._activeUser; } try { const res = await got.post(url, { ...gotOptions, json, method, body, headers, }); return res.body as R; } catch (err) { console.error(`NotionAPI error: ${err.message}`); throw err; } } private async getSignedFileUrls( urls: SignedUrlRequest[], gotOptions?: OptionsOfJSONResponseBody ): Promise<signedurlresponse> { return this.fetch<signedurlresponse>({ endpoint: "getSignedFileUrls", body: { urls }, gotOptions, }); } private async getBlocks( blockIds: string[], gotOptions?: OptionsOfJSONResponseBody ): Promise<notion.pagechunk> { return this.fetch<notion.pagechunk>({ endpoint: "syncRecordValues", body: { requests: blockIds.map((blockId) => ({ id: blockId, table: "block", version: -1, })), }, gotOptions, }); } } </notion.pagechunk></notion.pagechunk></signedurlresponse></signedurlresponse></string></r></notion.collectioninstance></notion.pagechunk></notion.extendedrecordmap></https:>
Langkah 3: Gunakan Encapsulated API dalam Next.js Pages
Untuk mengambil kandungan pangkalan data Notion dalam halaman Next.js anda, anda boleh menggunakan kelas NotionAPI terkapsul dan menghantar data yang diambil kepada komponen reaksi-notion-x untuk pemaparan.
// pages/[pageId].tsx import { GetServerSideProps } from 'next'; import { NotionAPI } from '../lib/NotionAPI'; import { NotionRenderer } from 'react-notion-x'; import 'react-notion-x/src/styles.css'; export const getServerSideProps: GetServerSideProps = async (context) => { const { pageId } = context.params; const notion = new NotionAPI(); const recordMap = await notion.getPage(pageId as string); return { props: { recordMap, }, }; }; const NotionPage = ({ recordMap }) => { return <notionrenderer recordmap="{recordMap}" fullpage="{true}" darkmode="{false}"></notionrenderer>; }; export default NotionPage;
Langkah 4: Konfigurasikan Penghalaan dalam Next.js
Untuk memastikan bahawa fail [pageId].tsx boleh memaparkan halaman Notion yang berbeza secara dinamik, anda perlu menyediakan penghalaan dinamik dalam Next.js. Ini akan membolehkan anda memadankan parameter pageId dan mengambil kandungan halaman Notion yang sepadan.Berikut ialah cara anda boleh mengkonfigurasi laluan dinamik:
- Buat Fail Laluan Dinamik dalam direktori halaman:
pages/[pageId].tsx
- Laksanakan Perenderan Halaman Dinamik:
Contoh kod:
import { GetStaticProps, GetStaticPaths } from 'next'; import { NotionRenderer } from 'react-notion-x'; import { getNotionPageData } from '../lib/NotionAPI'; import 'react-notion-x/src/styles.css'; export default function NotionPage({ pageData }) { return ( <div> <notionrenderer recordmap="{pageData}" fullpage="{true}" darkmode="{false}"></notionrenderer> </div> ); } export const getStaticProps: GetStaticProps = async ({ params }) => { const { pageId } = params!; const pageData = await getNotionPageData(pageId as string); return { props: { pageData, }, revalidate: 10, // Revalidate content every 10 seconds (ISR) }; }; export const getStaticPaths: GetStaticPaths = async () => { return { paths: [], // We’ll use fallback to handle dynamic routes fallback: 'blocking', // Generate pages on the fly if not pre-rendered }; };
- Explanation:
- getStaticPaths: Since your content is dynamic, we return an empty array for paths and set fallback: 'blocking' to generate pages on demand.
- getStaticProps: Fetches the Notion page content based on the pageId passed in the URL.
Summary
By following the steps above, you can now encapsulate Notion API requests and render Notion pages dynamically in your Next.js project using react-notion-x. This setup allows you to efficiently integrate Notion as a CMS while ensuring scalability and maintainability in your Next.js application.
Atas ialah kandungan terperinci [Laman Web Peribadi] Cara Mengintegrasikan Pangkalan Data Notion dalam Seterusnya. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Ya, teras enjin JavaScript ditulis dalam C. 1) Bahasa C menyediakan prestasi yang efisien dan kawalan asas, yang sesuai untuk pembangunan enjin JavaScript. 2) Mengambil enjin V8 sebagai contoh, terasnya ditulis dalam C, menggabungkan kecekapan dan ciri-ciri berorientasikan objek C. 3) Prinsip kerja enjin JavaScript termasuk parsing, penyusun dan pelaksanaan, dan bahasa C memainkan peranan penting dalam proses ini.

JavaScript adalah di tengah -tengah laman web moden kerana ia meningkatkan interaktiviti dan dinamik laman web. 1) Ia membolehkan untuk menukar kandungan tanpa menyegarkan halaman, 2) memanipulasi laman web melalui Domapi, 3) menyokong kesan interaktif kompleks seperti animasi dan drag-and-drop, 4) mengoptimumkan prestasi dan amalan terbaik untuk meningkatkan pengalaman pengguna.

C dan JavaScript mencapai interoperabilitas melalui webassembly. 1) Kod C disusun ke dalam modul WebAssembly dan diperkenalkan ke dalam persekitaran JavaScript untuk meningkatkan kuasa pengkomputeran. 2) Dalam pembangunan permainan, C mengendalikan enjin fizik dan rendering grafik, dan JavaScript bertanggungjawab untuk logik permainan dan antara muka pengguna.

JavaScript digunakan secara meluas di laman web, aplikasi mudah alih, aplikasi desktop dan pengaturcaraan sisi pelayan. 1) Dalam pembangunan laman web, JavaScript mengendalikan DOM bersama -sama dengan HTML dan CSS untuk mencapai kesan dinamik dan menyokong rangka kerja seperti JQuery dan React. 2) Melalui reaktnatif dan ionik, JavaScript digunakan untuk membangunkan aplikasi mudah alih rentas platform. 3) Rangka kerja elektron membolehkan JavaScript membina aplikasi desktop. 4) Node.js membolehkan JavaScript berjalan di sisi pelayan dan menyokong permintaan serentak yang tinggi.

Python lebih sesuai untuk sains data dan automasi, manakala JavaScript lebih sesuai untuk pembangunan front-end dan penuh. 1. Python berfungsi dengan baik dalam sains data dan pembelajaran mesin, menggunakan perpustakaan seperti numpy dan panda untuk pemprosesan data dan pemodelan. 2. Python adalah ringkas dan cekap dalam automasi dan skrip. 3. JavaScript sangat diperlukan dalam pembangunan front-end dan digunakan untuk membina laman web dinamik dan aplikasi satu halaman. 4. JavaScript memainkan peranan dalam pembangunan back-end melalui Node.js dan menyokong pembangunan stack penuh.

C dan C memainkan peranan penting dalam enjin JavaScript, terutamanya digunakan untuk melaksanakan jurubahasa dan penyusun JIT. 1) C digunakan untuk menghuraikan kod sumber JavaScript dan menghasilkan pokok sintaks abstrak. 2) C bertanggungjawab untuk menjana dan melaksanakan bytecode. 3) C melaksanakan pengkompil JIT, mengoptimumkan dan menyusun kod hot-spot semasa runtime, dan dengan ketara meningkatkan kecekapan pelaksanaan JavaScript.

Aplikasi JavaScript di dunia nyata termasuk pembangunan depan dan back-end. 1) Memaparkan aplikasi front-end dengan membina aplikasi senarai TODO, yang melibatkan operasi DOM dan pemprosesan acara. 2) Membina Restfulapi melalui Node.js dan menyatakan untuk menunjukkan aplikasi back-end.

Penggunaan utama JavaScript dalam pembangunan web termasuk interaksi klien, pengesahan bentuk dan komunikasi tak segerak. 1) kemas kini kandungan dinamik dan interaksi pengguna melalui operasi DOM; 2) pengesahan pelanggan dijalankan sebelum pengguna mengemukakan data untuk meningkatkan pengalaman pengguna; 3) Komunikasi yang tidak bersesuaian dengan pelayan dicapai melalui teknologi Ajax.


Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Penyesuai Pelayan SAP NetWeaver untuk Eclipse
Integrasikan Eclipse dengan pelayan aplikasi SAP NetWeaver.

Versi Mac WebStorm
Alat pembangunan JavaScript yang berguna

SublimeText3 Linux versi baharu
SublimeText3 Linux versi terkini

MinGW - GNU Minimalis untuk Windows
Projek ini dalam proses untuk dipindahkan ke osdn.net/projects/mingw, anda boleh terus mengikuti kami di sana. MinGW: Port Windows asli bagi GNU Compiler Collection (GCC), perpustakaan import yang boleh diedarkan secara bebas dan fail pengepala untuk membina aplikasi Windows asli termasuk sambungan kepada masa jalan MSVC untuk menyokong fungsi C99. Semua perisian MinGW boleh dijalankan pada platform Windows 64-bit.
