npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@syneki/notion-cms

v1.0.0

Published

<p align="center"> <img width="300" alt="NotionCMS" src="docs/logo.png"> </p>

Downloads

8

Readme

Use Notion as a Content Management System.

PRs Welcome Commitizen friendly License

@syneki/notion-cms @syneki/notion-renderer

Powered by Syneki Managed with

🚀 Get started🔧 Configure🔍 Query🏗 Extend

ContributeLicense

⚠ Pre-release

This project is currently in pre-release, you can use it but some features are lacking and few things will have to change in a near future.

  • [x] Query multiple pages from a database
  • [x] Query a single page
  • [x] Transform page content into HTML
  • [x] Ability to extends the renderer
  • [x] Easily map your page properties
  • [x] Ability to create custom parsers
  • [ ] Create renderer for all of the Notion base blocks
  • [ ] Handle relation property
  • [x] Handle page cover
  • [x] Handle file property
  • [ ] Handle rollup property

Do not hesitate to open an issue to provide your feedback, report bugs and to propose new features.

🚀 Getting started

Install libraries

$ npm install @syneki/notion-cms @syneki/notion-renderer
$ yarn add @syneki/notion-cms @syneki/notion-renderer

⚠ We highly recommend to use a Static Website Generator to use NotionCMS. The Notion API is extremely slow, avoid querying it on each visit.

Create a database

My integrations

Query your database

import { NotionCMS, NotionDatabase } from '@syneki/notion-cms';

const cms = new NotionCMS({
  auth: process.env.NOTION_TOKEN,
  renderer,
});

const database = new NotionDatabase({
  cms,
  databaseId: '<my-database-id>',
});

// Query multiple pages
const posts = await database.list();

// Retreive a single page by ID
const post = await database.get('<my-page-id>');

// Retreive a single page by property
const postBySlug = await database.findFirst({
  property: 'slug',
  rich_text: { equals: 'my-super-post' },
});

// Retreive the content of a page in HTML
const content = await database.getContent(postBySlug.id);

Get a Notion Token

To interact with Notion you need to create an integration and give it the correct permissions.

Create a new integration by heading to the following link.

You should then be able to get an Internal Integration Token.

:warning: Make sure that you are giving the correct permissions. If the token is directly accessible from your Frontend it can be a real problem!

My integrations

Add the integration to your databases

On each databases you want to query click on the ••• in the top right corner.

Click on Add connection and select your Integration. Your token should now have access to your database.

🔧 Configure

NotionCMS

NotionCMS is used to interact with a Notion Account.

import { NotionCMS } from '@syneki/notion-cms';

const cms = new NotionCMS({
  auth: '<your-authentication-token>', // Your Notion Internal Integration Token
  renderer: notionRenderer, // A NotionRenderer instance
  parser: notionParser, // A NotionParser instance
});

NotionDatabase

The NotionDatabase is used to interact with a specific Notion database.

import { NotionDatabse } from '@syneki/notion-cms';

const database = new NotionDatabase({
  cms: notionCMS, // Your NotionCMS instance
  databaseId: '<my-database-id>', // The ID of the Notion Database
  mapping: {
    title: {
      // The property key of the final object
      name: 'Title', // The name of the page Property
      id: 'title', // The id of the page Property
    },
    shortDescription: {
      name: 'Short description',
    },
  },
});

The mapping is optionnal, if you do not specify it, the keys will be taken from the properties name.

Read more on how to query your pages.

ℹ You can find the Database ID from the URL on the page.

NotionRenderer

The NotionRenderer instance is used to transform properties and content into HTML. It accepts custom Blocks.

Read more on how to extend.

import { NotionRenderer } from '@syneki/notion-renderer';

const renderer = new NotionRenderer(ParagraphBlock, TaskBlock);

🔍 Query

List pages of a database

import { NotionDatabase } from '@syneki/notion-cms';

const database = new NotionDatabse({ ... })

const posts = await database.list()

const posts = await database.list({
    // Filtering
    filter: {
        property: 'Status', // The property name
        type: 'status', // The property type
        status: {
            equals: 'Published' // What status you want to query
        }
    },

    // Pagination
    pageSize: 2, // The number of pages to query
    cursor: '<cursor>', // At what page the list starts

    // Sorting [WIP]
})

Query a single page by ID

import { NotionDatabase } from '@syneki/notion-cms';

const database = new NotionDatabse({ ... })

const post = await database.get('<page-id>');

Query a single page by property

import { NotionDatabase } from '@syneki/notion-cms';

const database = new NotionDatabse({ ... })

const post = await database.findFirst({
    property: 'Slug',
    rich_text: {
        equals: 'my-super-post'
    }
})

Get the content of a page

When querying pages, you will only get the properties. You must query the content with the getContent method.

The content is automatically rendered into HTML.

import { NotionDatabase } from '@syneki/notion-cms';

const database = new NotionDatabse({ ... })

const post = await database.findFirst({
    property: 'Slug',
    rich_text: {
        equals: 'my-super-post'
    }
})

const content = await database.getContent(post.id);

🏗 Extend

Parsers

Parsers transform page properties sent by the Notion API.

For example, a date property in Notion results in a string but we parse it to transform it into a Date and make it directly accessible into the final object.

In the following examples we replace the first part of each email with fake data.

import { faker } from '@faker-js/faker';
import { NotionParser, NotionCMS, PropertyParser } from '@syneki/notion-cms';

const fakeEmailParser: PropertyParser<string, string> = (data) => {
  const domain = data.email.split('@').at(-1);
  return `${faker.internet.userName()}@${domain}`;
};

// Add it through the constructor
const parser = new NotionParser({
  propertyParsers: {
    email: fakeEmailParser,
  },
});

// Or with the method addParser
parser.addParser('email', fakeEmailParser);

// Use it in NotionCMS
const cms = new NotionCMS({ parser });

Renderers

Notion does not transform the rich content into HTML. It returns a JSON object with the configuration of each block.

You can add custom renderer to override the current Renderers or to handle more blocks.

import { createBlockRenderer, NotionRenderer } from '@syneki/notion-renderer';

const customParagraphRenderer = createBlockRenderer(
  'paragraph',
  (data, renderer) => {
    return `<p class="custom-paragraph">${renderer.render(
      ...data.paragraph.rich_text
    )}</p>`;
  }
);

// Add it through the constructor
const renderer = new NotionRenderer(customParagraphRenderer);
// Or with the method addBlockRenderer
renderer.addBlockRenderer(customParagraphRenderer);

// Use it in NotionCMS
const cms = new NotionCMS({ renderer });

As you can see we can render Blocks into blocks. In this case a Code Block contains Rich text, we call the renderer.render method to render it with the RichTextRenderer.

Contributing

Licence

Copyright © 2022 Syneki

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.