Skip to content

Commit ecf19aa

Browse files
feat: add loading state to full demo
1 parent 65e4d74 commit ecf19aa

File tree

5 files changed

+107
-5
lines changed

5 files changed

+107
-5
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import * as React from 'react'
2+
import { LoadingIcon } from './LoadingIcon'
3+
4+
import styles from './styles.module.css'
5+
6+
export const Loading: React.FC = () => (
7+
<div className={styles.container}>
8+
<LoadingIcon />
9+
</div>
10+
)
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import * as React from 'react'
2+
import cs from 'classnames'
3+
import styles from './styles.module.css'
4+
5+
export const LoadingIcon = (props) => {
6+
const { className, ...rest } = props
7+
return (
8+
<svg
9+
className={cs(styles.loadingIcon, className)}
10+
{...rest}
11+
viewBox='0 0 24 24'
12+
>
13+
<defs>
14+
<linearGradient
15+
x1='28.1542969%'
16+
y1='63.7402344%'
17+
x2='74.6289062%'
18+
y2='17.7832031%'
19+
id='linearGradient-1'
20+
>
21+
<stop stopColor='rgba(164, 164, 164, 1)' offset='0%' />
22+
<stop
23+
stopColor='rgba(164, 164, 164, 0)'
24+
stopOpacity='0'
25+
offset='100%'
26+
/>
27+
</linearGradient>
28+
</defs>
29+
30+
<g id='Page-1' stroke='none' strokeWidth='1' fill='none'>
31+
<g transform='translate(-236.000000, -286.000000)'>
32+
<g transform='translate(238.000000, 286.000000)'>
33+
<circle
34+
id='Oval-2'
35+
stroke='url(#linearGradient-1)'
36+
strokeWidth='4'
37+
cx='10'
38+
cy='12'
39+
r='10'
40+
/>
41+
<path
42+
d='M10,2 C4.4771525,2 0,6.4771525 0,12'
43+
id='Oval-2'
44+
stroke='rgba(164, 164, 164, 1)'
45+
strokeWidth='4'
46+
/>
47+
<rect
48+
id='Rectangle-1'
49+
fill='rgba(164, 164, 164, 1)'
50+
x='8'
51+
y='0'
52+
width='4'
53+
height='4'
54+
rx='8'
55+
/>
56+
</g>
57+
</g>
58+
</g>
59+
</svg>
60+
)
61+
}

examples/full/components/NotionPage.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@ import Head from 'next/head'
33
import Link from 'next/link'
44
import Image from 'next/image'
55
import dynamic from 'next/dynamic'
6+
import { useRouter } from 'next/router'
67

78
import { NotionRenderer } from 'react-notion-x'
89
import { ExtendedRecordMap } from 'notion-types'
910
import { getPageTitle } from 'notion-utils'
1011
import { Tweet, TwitterContextProvider } from 'react-static-tweets'
1112

13+
import { Loading } from './Loading'
14+
1215
// -----------------------------------------------------------------------------
1316
// dynamic imports for optional components
1417
// -----------------------------------------------------------------------------
@@ -48,6 +51,12 @@ export const NotionPage = ({
4851
rootPageId?: string
4952
rootDomain?: string
5053
}) => {
54+
const router = useRouter()
55+
56+
if (router.isFallback) {
57+
return <Loading />
58+
}
59+
5160
if (!recordMap) {
5261
return null
5362
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
@keyframes spinner {
2+
to {
3+
transform: rotate(360deg);
4+
}
5+
}
6+
7+
.container {
8+
width: 100%;
9+
min-height: 100vh;
10+
display: flex;
11+
justify-content: center;
12+
align-items: center;
13+
padding: calc(min(2vmin, 24px));
14+
}
15+
16+
.loadingIcon {
17+
animation: spinner 0.6s linear infinite;
18+
display: block;
19+
width: 24px;
20+
height: 24px;
21+
color: rgba(55, 53, 47, 0.4);
22+
}

readme.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
If you just want to publish a website using Notion, then we highly recommend using [Super.so](https://s.super.so/x) — a hosted solution with great perf that takes care of all the details for you.
3030

31-
If you want more control over your website via React, we recommend using either `react-notion-x` or the accompanying [Next.js starter kit](https://github.com/transitive-bullshit/nextjs-notion-starter-kit), which is free and uses `react-notion-x` under the hood.
31+
If you want more control over your website via React, then we recommend checking out the accompanying [Next.js starter kit](https://github.com/transitive-bullshit/nextjs-notion-starter-kit), which is free and uses `react-notion-x` under the hood.
3232

3333
And if you want even more control, then you're in the right place! 👇👇
3434

@@ -40,7 +40,7 @@ And if you want even more control, then you're in the right place! 👇👇
4040
- Heavier components can be loaded lazily via `next/dynamic`
4141
- 💯 **Tests** - Comes with a comprehensive [test suite](https://www.notion.so/Notion-Test-Suite-067dd719a912471ea9a3ac10710e7fdf) covering most of Notion's functionality
4242
- 🔥 **Solid** - Used in production by [Potion](https://www.potion.so) and thousands of websites
43-
- 💪 **Smooth** - Supports `next/image` along with LQIP preview images ([demo](https://react-notion-x-demo.transitivebullsh.it/image-sizing-3492bd6dbaf44fe7a5cac62c5d402f06))
43+
- 💪 **Smooth** - Supports `next/image` along with LQIP preview images ([demo](https://react-notion-x-demo.transitivebullsh.it/3492bd6dbaf44fe7a5cac62c5d402f06))
4444
- Framework agnostic - Use with next.js, create-react-app, gatsby, etc
4545

4646
## Usage
@@ -68,7 +68,7 @@ export default ({ recordMap }) => (
6868

6969
You may optionally pass an `authToken` to the API if you want to access private Notion resources.
7070

71-
Note: for heavier blocks, you'll have to opt into using them via `NotionRenderer.components`. These are not included in the default `NotionRenderer` export because they're too heavyweight for the majority of use cases.
71+
Note: for heavier blocks, you'll have to opt into using them via `NotionRenderer.components`. These are not included in the default `NotionRenderer` export because they're too heavyweight for a lot of use cases.
7272

7373
## Styles
7474

@@ -247,12 +247,12 @@ Bundlephobia reports a [~27.5kb gzip bundle size](https://bundlephobia.com/resul
247247

248248
Another major factor for perf comes from images hosted by Notion. They're generally unoptimized, improperly sized, and not cacheable because Notion has to deal with fine-grained access control that users can change at any time. You can override the default `mapImageUrl` function on `NotionRenderer` to add caching via a CDN like Cloudflare Workers, which is what Notion X does for optimal page load speeds.
249249

250-
`NotionRenderer` also supports lazy image loading with optional low quality image placeholder previews. You can see a demo of this in practice [on this page](https://react-notion-x-demo.transitivebullsh.it/image-sizing-3492bd6dbaf44fe7a5cac62c5d402f06) which is using [lqip-modern](https://github.com/transitive-bullshit/lqip-modern) to pre-generate placeholder images that are inspired by Medium.com's image loading.
250+
`NotionRenderer` also supports lazy image loading with optional low quality image placeholder previews. You can see a demo of this in practice [on this page](https://react-notion-x-demo.transitivebullsh.it/3492bd6dbaf44fe7a5cac62c5d402f06) which is using [lqip-modern](https://github.com/transitive-bullshit/lqip-modern) to pre-generate placeholder images that are inspired by Medium.com's image loading.
251251

252252
<p align="center">
253253
<img alt="Google Lighthouse Scores" src="https://raw.githubusercontent.com/NotionX/react-notion-x/master/media/react-notion-x-perf.png" width="600" />
254254
<br>
255-
<i>Google Lighthouse scores for an <a href="https://react-notion-x-demo.transitivebullsh.it/checklists-38fa73d49b8f40aab1f3f8c82332e518">example page</a> hosted by Notion X.</i>
255+
<i>Google Lighthouse scores for an <a href="https://react-notion-x-demo.transitivebullsh.it/38fa73d49b8f40aab1f3f8c82332e518">example page</a> rendered by `react-notion-x` on Vercel.</i>
256256
</p>
257257

258258
## Related

0 commit comments

Comments
 (0)