Skip to content

Commit

Permalink
feat(server): add experimental support for React Server Components an…
Browse files Browse the repository at this point in the history
…d Next.js app directory (#5827)

* feat(rsc): very experimental working PoC for Next.js app dir

* feat(`react-instantsearch-ssr-nextjs`): turn Next.js RSC/SSR solution into its own package (#5830)

* chore: create `react-instantsearch-ssr-nextjs` package

* chore: move Next.js RSC/SSR utilities to dedicated package

* docs: update Next App Router example with new package

* refactor: split context and usage Hook

* feat: pass `ServerInsertedHTMLContext` ourselves

* refactor: clean up importqs

* style: lint

* docs: build example in CodeSandbox

* ci: use Next.js 13 compatible Node version

* ci: use compatible Node version

* test: add version test files

* upgrade next version in all examples

* chore: remove unnecessary exports

* chore: remove weirdo character

* build: resolve Next for ESM

* refactor: move as much logic in new package as possible + dynamicWidgets support

* routing

---------

Co-authored-by: Dhaya <154633+dhayab@users.noreply.github.com>
Co-authored-by: Aymeric Giraudet <aymeric.giraudet@algolia.com>

* fix other next examples

* update deps in new package

* fix build/tests?

* bundlesize

* React import in app-dir example

* feat(RSC): add warnings (#5840)

* bump node version a bit

* avoid double results injection

* fix: routing when going from one InstantSearch page to another

Co-authored-by: Burak Tamtürk <buraktamturk@gmail.com>

* fix tests

* changed naming

* fix build

* forgot to rename dir

* fix multi index

* revert to renderToString

* remove doctoc line

* readme

* changed use

* update peerDep

* Apply suggestions from code review

Co-authored-by: Dhaya <154633+dhayab@users.noreply.github.com>

---------

Co-authored-by: Sarah Dayan <5370675+sarahdayan@users.noreply.github.com>
Co-authored-by: Dhaya <154633+dhayab@users.noreply.github.com>
Co-authored-by: Burak Tamtürk <buraktamturk@gmail.com>
  • Loading branch information
4 people authored Sep 19, 2023
1 parent 8b06c47 commit 44de9ec
Show file tree
Hide file tree
Showing 47 changed files with 1,301 additions and 161 deletions.
3 changes: 2 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ references:
defaults: &defaults
working_directory: ~/instantsearch
docker:
- image: cimg/node:14.18.0
- image: cimg/node:16.14.0

workflows:
version: 2
Expand Down Expand Up @@ -163,6 +163,7 @@ jobs:
- packages/react-instantsearch/dist
- packages/react-instantsearch-core/dist
- packages/react-instantsearch-router-nextjs/dist
- packages/react-instantsearch-nextjs/dist
- packages/vue-instantsearch/vue2
- packages/vue-instantsearch/vue3

Expand Down
4 changes: 3 additions & 1 deletion .codesandbox/ci.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@
"instantsearchjs-es-template-pcw1k",
"github/algolia/instantsearch/tree/templates/react-instantsearch",
"/examples/react/default-theme",
"/examples/react/next-app-router",
"/examples/vue/default-theme"
],
"buildCommand": "build --no-private --ignore *-maps --ignore *-native",
"packages": [
"packages/instantsearch.js",
"packages/react-instantsearch",
"packages/react-instantsearch-core",
"packages/react-instantsearch-nextjs",
"packages/vue-instantsearch",
"packages/instantsearch.css"
],
"node": "14"
"node": "16"
}
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
14.18.0
16.14.0
2 changes: 2 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ module.exports = (api) => {
'react-dom',
// `use-sync-external-store` also fails if the paths are incomplete
'use-sync-external-store',
// `next` imports as peer dependencies fail if paths are incomplete
'next',
],
},
],
Expand Down
2 changes: 1 addition & 1 deletion bundlesize.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
},
{
"path": "packages/react-instantsearch/dist/umd/ReactInstantSearch.min.js",
"maxSize": "56 kB"
"maxSize": "56.25 kB"
},
{
"path": "packages/vue-instantsearch/vue2/umd/index.js",
Expand Down
4 changes: 2 additions & 2 deletions examples/react/default-theme/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
"dependencies": {
"algoliasearch": "4.14.3",
"instantsearch.js": "4.56.11",
"react": "18.1.0",
"react-dom": "18.1.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-instantsearch": "7.0.3"
},
"devDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions examples/react/e-commerce/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
"dependencies": {
"algoliasearch": "4.14.3",
"instantsearch.js": "4.56.11",
"react": "18.1.0",
"react": "18.2.0",
"react-compound-slider": "3.4.0",
"react-dom": "18.1.0",
"react-dom": "18.2.0",
"react-instantsearch": "7.0.3"
},
"devDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions examples/react/getting-started/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
"dependencies": {
"algoliasearch": "4.14.3",
"instantsearch.js": "4.56.11",
"react": "18.1.0",
"react-dom": "18.1.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-instantsearch": "7.0.3"
},
"devDependencies": {
Expand Down
9 changes: 9 additions & 0 deletions examples/react/next-app-router/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": ["plugin:@next/next/recommended"],
"rules": {
// This rule is not able to find the `pages/` folder in the monorepo.
"@next/next/no-html-link-for-pages": ["off"],
"react/react-in-jsx-scope": "off",
"spaced-comment": ["error", "always", { "markers": ["/"] }]
}
}
34 changes: 34 additions & 0 deletions examples/react/next-app-router/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local

# vercel
.vercel
18 changes: 18 additions & 0 deletions examples/react/next-app-router/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
This example shows how to do server side rendering with next.js and React InstantSearch. There's a live example here: https://codesandbox.io/s/github/algolia/instantsearch.js/tree/master/examples/react/next.

[![Edit next](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/algolia/instantsearch/tree/master/examples/react/next)

## Clone the example

```sh
curl https://codeload.github.com/algolia/instantsearch/tar.gz/master | tar -xz --strip=3 instantsearch-master/examples/react/next
```

## Start the example

```sh
yarn install --no-lockfile
yarn run dev
```

Read more about React InstantSearch [in our documentation](https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/react/).
57 changes: 57 additions & 0 deletions examples/react/next-app-router/app/Search.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
'use client';

import algoliasearch from 'algoliasearch/lite';
import { Hit as AlgoliaHit } from 'instantsearch.js';
import React from 'react';
import {
Hits,
Highlight,
SearchBox,
RefinementList,
DynamicWidgets,
} from 'react-instantsearch';
import { InstantSearchNext } from 'react-instantsearch-nextjs';

import { Panel } from '../components/Panel';

const client = algoliasearch('latency', '6be0576ff61c053d5f9a3225e2a90f76');

type HitProps = {
hit: AlgoliaHit<{
name: string;
price: number;
}>;
};

function Hit({ hit }: HitProps) {
return (
<>
<Highlight hit={hit} attribute="name" className="Hit-label" />
<span className="Hit-price">${hit.price}</span>
</>
);
}

export default function Search() {
return (
<InstantSearchNext searchClient={client} indexName="instant_search" routing>
<div className="Container">
<div>
<DynamicWidgets fallbackComponent={FallbackComponent} />
</div>
<div>
<SearchBox />
<Hits hitComponent={Hit} />
</div>
</div>
</InstantSearchNext>
);
}

function FallbackComponent({ attribute }: { attribute: string }) {
return (
<Panel header={attribute}>
<RefinementList attribute={attribute} />
</Panel>
);
}
Binary file added examples/react/next-app-router/app/favicon.ico
Binary file not shown.
22 changes: 22 additions & 0 deletions examples/react/next-app-router/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
html,
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}

body {
padding: 0.5rem;
}

* {
box-sizing: border-box;
}

.Container {
display: grid;
align-items: flex-start;
grid-template-columns: minmax(min-content, 200px) 1fr;
gap: 0.5rem;
}
20 changes: 20 additions & 0 deletions examples/react/next-app-router/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import './globals.css';
import 'instantsearch.css/themes/satellite-min.css';
import React from 'react';

export const metadata = {
title: 'Next.js',
description: 'Generated by Next.js',
};

export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
Loading

0 comments on commit 44de9ec

Please sign in to comment.