Closed transitive-bullshit closed 3 years ago
Wow, thanks for sharing all your hard work! A lot of great improvements have been made with react-notion-x
.
Moving forwards I'd love to leverage a lot of the stuff you built. I outlined some of my thoughts on how to implement those changes, while remaining true to the vision of providing a minimal content renderer for Notion in #37.
Those are the things I think make sense to look into:
notion-types
& notion-utils
packages. They are quite unopinionated, and mostly dictated by what Notion does. Makes sense to solve those problems on dedicated packages, like you did. 👍 notion-client
for notion-api-worker
(cc @tobiaslins). Same as above, makes sense to focus that work in one central point, and make it reusable for other projects. As you mentioned is a good idea to directly talk to the API when using Next.js. For projects that are not using Node or need client-side communication, I still think the worker still has it's place. Also the /table
functionality is not handled by notion-client
- not sure if it should, since I like the idea of it being just the a bare Notion API client without a lot of custom logic. Maybe the need for the /table
endpoints will be redundant once they launch the official API.Lazy loading complex blocks is definitely a good idea. I would try to avoid depending on next/dynamic
, since this rules out applications in other environments like Gatsby or manual SSR. I will put the new custom component system to the test, maybe it can provide a way to bring your own™ lazy load system.
React Notion X
Context
The purpose of this thread is to give some context between these two projects and track their differences, with the goal of ultimately converging on a single solution for the React Notion community going forwards.
I've spent the past few months working to improve
react-notion
for Notion2Site. Towards that end, I've had several conversations with @tobiaslins and @timolins who did a lot of the amazing legwork in creating the first version ofreact-notion
.I was working on a fork of
react-notion
with all of my changes in a Next.js project (not a Git fork, unfortunately), and I finally found the time to move this fork back out into its own set of standalone packages: react-notion-x.Summary of changes
The largest changes can be broken into a few themes:
I'll go into a bit more depth on some of these below.
Packages
One of the biggest changes is structural. Instead of relying on a CF worker and having types and utilities duplicated between
react-notion
andnotion-api-worker
, all of this has been split into isolated packages:imho it makes a lot more sense to expose a Notion API wrapper as
notion-client
that can be used from Node.js (and Next.js SSR), Deno, etc instead of just CF workers.The goal is that hopefully once Notion releases its public API, these packages should only require minor updates with
react-notion-x
not having to change much if at all.New Blocks
General Improvements
next/dynamic
as a peer dep (eg, PDF support, collection support, equations / katex, etc)Performance
I know one of the things that Tobias and Timo expressed very fair concerns about has been how to manage the tradeoffs between
react-notion
's original goal of being extremely lightweight and focused on embeddable use cases versusreact-notion-x
's goal of faithfully supporting all Notion content with both embedded and full page use cases.This is very closely related to perf and bundle size, two things which I've spent a lot of time working on with
react-notion-x
, though there are definitely lots of tradeoffs to consider here.I go into a bit more depth about my approach here, but in general I think that lazy loading larger optional dependencies like
react-pdf
,react-katex
, as well as heavier portions ofreact-notion
like collection views and equation support, gets us the best of both worlds.The first load JS and total JS bundle size for most pages is comparable with
react-notion
, with larger optional dependencies only being loaded if needed by any given page.The net result is that it's pretty easy to get solid lighthouse perf scores.
One downside of this approach is that I'm not sure how adding
next/dynamic
as a peer dependency works for devs who may want to use React Notion from non-Next.js projects. Does anyone have any good examples of large third-party React libraries that support loading portions of their bundle dynamically (and work regardless of if the consuming app is using Webpack or another bundler)?Design
react-notion-x
started as a fork ofreact-notion
, and although 90% of the code has changed, the coreNotionRenderer
andBlock
classes should look very similar.I took a very similar approach to https://github.com/splitbee/react-notion/pull/30 via @cball in supporting the ability to override specific components via a
components
prop onNotionRenderer
.Conversely, I ended up finding that as the number of components and their complexity grew, it became significantly simpler to expose an internal-only
NotionContext
that gives sub-components access to this configuration. It also became necessary for some interesting cases where when you render some subtrees, you want to completely negate the possibility of using<a>
tags even though that subtree could contain any type of blocks. You can see an example of this in CollectionCard which can contain lots of different types of property content that we want to ensure doesn't contain any links so we overridecomponents.link
andcomponents.pageLink
with a dummy link component.Closing Thoughts
I hope this gives a good overview of my changes to
react-notion-x
with an emphasis on the most important design decisions.I would've loved to have this be a real Git fork, but as I explained above this just wasn't in the cards for practical reasons as I learned about the scope of the changes needed as I went along.
Anyhow, I'm hoping that this public thread opens up a productive discussion that will benefit both projects and anyone interested in hacking on Notion in the future.
I'm very open to ideas about the best way to move both projects forward and hopefully merge them into a single
react-notion
solution that will provide the most long-term benefits.Thanks!