RORK LABJP
PLAY — Google Play's target API level 36 requirement took effect yesterday, August 31. From today, new apps and updates must target Android 16VISIBILITY — Apps still on API 35 stay listed but disappear for users on newer Android versions. No error is raised; new installs simply fade, which makes the change easy to missEXTENSION — If you missed the deadline, an extension through November 1, 2026 can be requested in Play Console — best filed alongside a concrete migration planAPPLE — On the Apple side, the event lands September 9 and iOS 27 is reported to ship September 14. Testing generated apps on iOS 27 hardware before release week is time well spentEXPO — Expo released expo-paste-input on August 28, a native module that brings image, GIF, and sticker paste to React Native TextInputEAS — EAS Observe reached general availability on August 20, putting crash and performance monitoring on the same EAS platform as builds and updatesPLAY — Google Play's target API level 36 requirement took effect yesterday, August 31. From today, new apps and updates must target Android 16VISIBILITY — Apps still on API 35 stay listed but disappear for users on newer Android versions. No error is raised; new installs simply fade, which makes the change easy to missEXTENSION — If you missed the deadline, an extension through November 1, 2026 can be requested in Play Console — best filed alongside a concrete migration planAPPLE — On the Apple side, the event lands September 9 and iOS 27 is reported to ship September 14. Testing generated apps on iOS 27 hardware before release week is time well spentEXPO — Expo released expo-paste-input on August 28, a native module that brings image, GIF, and sticker paste to React Native TextInputEAS — EAS Observe reached general availability on August 20, putting crash and performance monitoring on the same EAS platform as builds and updates
Articles/Dev Tools
Dev Tools/2026-04-23Advanced

Using Notion as a CMS Backend for Rork Apps — Auth, Block Rendering, Rate Limits, and the 1-Hour Image URL Problem

Put Notion behind your Rork app. Pick the right auth model, render Notion blocks safely, survive the 1-hour image URL expiry, and stay under the API rate limit — a production-grade walkthrough.

Notion APIRork547CMSOAuth2React Native234Caching2Rate Limiting

Premium Article

When a Rork-built app starts to feel like it needs actual articles, recipes, or lessons behind it, the backend question shows up uninvited. Firestore feels heavy to wire up from scratch. Supabase adds infrastructure you now have to think about. Sanity or Contentful are wonderful, but they might outclass a small project in ways you can feel in your wallet. I have spent the last few years quietly using Notion as the backend for exactly these "right-sized" apps — and it holds up better than you might expect.

Notion's appeal is almost embarrassingly practical. Writers can edit in a tool they already know. Titles, bodies, tags, and publish flags fall out of a database without you designing anything. Write in Notion, read in Rork — that split cuts friction out of the "write, fix, ship" loop that indie developers live and die by.

That said, Notion's API has three quirks you absolutely want to know before shipping. Image URLs expire after one hour, the API has a rate limit you will notice eventually, and page content comes back as a peculiar array of blocks. Miss any of those and the version of your app that launched just fine on Monday will greet you on Friday with "the images are gone" reports from confused readers.

This guide walks through using Notion as the CMS for a Rork-generated React Native app, including the operational lessons I earned the hard way across five indie projects. We're aiming for something that keeps working — not a cute sample that falls apart in week two.

Three questions to settle before you put Notion behind your app

Before wiring anything, clarify three things about your app. It saves design regret later.

1. Read-only, or read-write? Blogs, news, recipes — anywhere "I write, readers read" — are a clean fit. If you need user-submitted content, Notion is the wrong tool. The API supports writes, but funneling strangers' content into your own workspace is an operational mess. Supabase or Firestore are much saner there.

2. One language, or many? For multilingual apps you have two shapes: one row per language (with a locale property), or one row with title_ja, title_en columns side by side. I prefer the former. Translation progress is easier to track, and "publish Japanese today, hold the English until next week" just works.

3. Image-heavy, or text-heavy? Image-heavy apps (recipes, travel guides, portfolios) must plan for the 1-hour expiry before writing a single line of frontend code. Text-heavy apps can ship a much simpler version.

Once those three are settled, the rest of the work flows straight.

Start with an Internal Integration Token; reach for OAuth only when you must

Notion gives you two auth paths.

  • Internal Integration Token — read and write your own workspace. Mint a token, send it as Authorization: Bearer, and you're online.
  • Public OAuth — let other users connect their workspaces. Needed for multi-workspace SaaS-style products.

If you're a solo developer shipping your own writing to your own app, start with an Internal Integration Token. Building OAuth first — callback handling, encrypted token storage, refresh flows — quietly eats a week before you render a single paragraph.

There is one rule, though, that you cannot bend: never put the token in the client bundle. Dropping NOTION_TOKEN=secret_xxx into a Rork-generated .env that ships with the app is a leak waiting to happen. The token belongs on a server (Cloudflare Workers, a tiny Hono BFF, whatever you have) and the app always talks to Notion through that server.

A minimal backend needs exactly three endpoints: list articles, get one article, and proxy images. The Hono setup from Rork × Hono Cloudflare Workers REST API Implementation Guide pairs cleanly with Notion and is what I'm using in the examples below.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
You'll settle the infamous '1-hour image URL expiry' with a proxy pattern that pairs short-TTL edge caching and signed URL refresh — no more broken images the day after launch
You'll learn where Internal Integration Tokens end and public OAuth begins, so you can start personal and scale to multi-workspace without rewriting your auth layer
You'll build a type-safe block renderer that survives Notion adding new block types tomorrow, turning your CMS into a reliable content pipeline rather than a weekly fire drill
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $15 for lifetime access
View Membership →

Related Articles

Dev Tools2026-06-25
When an Image-Heavy Rork App Quietly Bloats Its Cache and Dies on Memory — Field Notes on Measuring and Capping
In a Rork app where images are the product, expo-image's disk cache and resident memory creep up over a session and surface as OOM crashes. Here's how I measured the bloat, where I set caps, and what I trimmed on the delivery side — with working code, in the order that actually helped.
Dev Tools2026-08-22
Every bulk replace exited zero. The damage was in the lines I did not delete
Run a bulk replace over generated code and the breakage lands on the neighbouring lines, not the matched ones. Here is what broke in a live project, and a dependency-free guard that checks the invariants a replace must preserve.
Dev Tools2026-08-14
Find the native edits expo prebuild will erase before you upgrade to SDK 57
Expo SDK 57 makes expo prebuild clear and regenerate ios and android by default. Here is how to audit your hand edits first, move them into config plugins, and why 57.0.9 matters for Reanimated apps.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →