diff --git a/examples/history-sync-transit/.eslintrc.json b/examples/history-sync-transit/.eslintrc.json
new file mode 100644
index 00000000..a2569c2c
--- /dev/null
+++ b/examples/history-sync-transit/.eslintrc.json
@@ -0,0 +1,4 @@
+{
+ "root": true,
+ "extends": "next/core-web-vitals"
+}
diff --git a/examples/history-sync-transit/.gitignore b/examples/history-sync-transit/.gitignore
new file mode 100755
index 00000000..c917155c
--- /dev/null
+++ b/examples/history-sync-transit/.gitignore
@@ -0,0 +1,38 @@
+# 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*
+.pnpm-debug.log*
+
+# local env files
+.env*.local
+
+# vercel
+.vercel
+
+# typescript
+*.tsbuildinfo
+
+# yarn
+yarn.lock
diff --git a/examples/history-sync-transit/README.md b/examples/history-sync-transit/README.md
new file mode 100755
index 00000000..92736a16
--- /dev/null
+++ b/examples/history-sync-transit/README.md
@@ -0,0 +1,8 @@
+## history-sync-json
+
+Example of `RecoilHistorySyncJSONNext`.
+
+```bash
+# run example application
+yarn dev
+```
diff --git a/examples/history-sync-transit/next-env.d.ts b/examples/history-sync-transit/next-env.d.ts
new file mode 100755
index 00000000..4f11a03d
--- /dev/null
+++ b/examples/history-sync-transit/next-env.d.ts
@@ -0,0 +1,5 @@
+///
+///
+
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/examples/history-sync-transit/next.config.js b/examples/history-sync-transit/next.config.js
new file mode 100755
index 00000000..e977df79
--- /dev/null
+++ b/examples/history-sync-transit/next.config.js
@@ -0,0 +1,11 @@
+/** @type {import('next').NextConfig} */
+const nextConfig = {
+ reactStrictMode: true,
+ swcMinify: true,
+ experimental: {
+ scrollRestoration: true,
+ newNextLinkBehavior: true,
+ },
+}
+
+module.exports = nextConfig
diff --git a/examples/history-sync-transit/package-copy.sh b/examples/history-sync-transit/package-copy.sh
new file mode 100755
index 00000000..bf0da2d0
--- /dev/null
+++ b/examples/history-sync-transit/package-copy.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+echo "[recoil-sync-next] copy to current directory..."
+
+CURRENT=`pwd`
+cd ../../
+yarn clean-build
+yarn pack --filename recoil-sync-next-local.tgz
+
+cd $CURRENT/node_modules
+rm -Rf recoil-sync-next/
+tar zxf ../../../recoil-sync-next-local.tgz
+mv package/ recoil-sync-next/
+
+cd ..
+rm -Rf .next/
+
+echo "[recoil-sync-next] copy success!"
+exit $?
diff --git a/examples/history-sync-transit/package.json b/examples/history-sync-transit/package.json
new file mode 100644
index 00000000..c251f0d3
--- /dev/null
+++ b/examples/history-sync-transit/package.json
@@ -0,0 +1,34 @@
+{
+ "name": "history-sync-json",
+ "version": "0.1.0",
+ "private": true,
+ "scripts": {
+ "inst": "yarn install",
+ "dev": "next dev",
+ "build": "next build",
+ "start": "next start",
+ "lint:eslint": "next lint",
+ "lint:tsc": "tsc --noEmit -p tsconfig.json",
+ "lint-fix:eslint": "next lint --fix",
+ "lint-fix:prettier": "prettier \"{pages,src,styles}/**/*.{ts,tsx,css}\" --write",
+ "local-build": "yarn run local-copy && yarn run build",
+ "local-dev": "yarn run local-copy && yarn run dev",
+ "local-copy": "./package-copy.sh"
+ },
+ "dependencies": {
+ "next": "^12.2.2",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "recoil": "^0.7.4",
+ "recoil-sync": "^0.1.0",
+ "recoil-sync-next": "latest"
+ },
+ "devDependencies": {
+ "@types/node": "^18.0.3",
+ "@types/react": "^18.0.15",
+ "@types/react-dom": "^18.0.6",
+ "eslint": "^8.19.0",
+ "eslint-config-next": "^12.2.2",
+ "typescript": "^4.7.4"
+ }
+}
diff --git a/examples/history-sync-transit/pages/_app.tsx b/examples/history-sync-transit/pages/_app.tsx
new file mode 100755
index 00000000..492ac27f
--- /dev/null
+++ b/examples/history-sync-transit/pages/_app.tsx
@@ -0,0 +1,17 @@
+import '../styles/globals.css'
+import { RecoilRoot } from 'recoil'
+import { RecoilHistorySyncJSONNext } from 'recoil-sync-next'
+
+import type { AppProps } from 'next/app'
+
+function MyApp({ Component, pageProps }: AppProps) {
+ return (
+
+
+
+
+
+ )
+}
+
+export default MyApp
diff --git a/examples/history-sync-transit/pages/index.tsx b/examples/history-sync-transit/pages/index.tsx
new file mode 100755
index 00000000..61b302a8
--- /dev/null
+++ b/examples/history-sync-transit/pages/index.tsx
@@ -0,0 +1,31 @@
+import Head from 'next/head'
+import Link from 'next/link'
+
+import { Counter } from '../src/components/Counter'
+import { Links } from '../src/components/Links'
+import { Textfield } from '../src/components/Textfield'
+import styles from '../styles/Home.module.css'
+
+import type { NextPage } from 'next'
+
+const Home: NextPage = () => {
+ return (
+
+
+
Top - Example of RecoilHistorySyncJSONNext
+
+
+
+
+ Top page (Static)
+
+
+
+
+
+
+
+ )
+}
+
+export default Home
diff --git a/examples/history-sync-transit/pages/ssg/[id].tsx b/examples/history-sync-transit/pages/ssg/[id].tsx
new file mode 100644
index 00000000..9d97d8bb
--- /dev/null
+++ b/examples/history-sync-transit/pages/ssg/[id].tsx
@@ -0,0 +1,56 @@
+import Head from 'next/head'
+
+import { Counter } from '../../src/components/Counter'
+import { Textfield } from '../../src/components/Textfield'
+import { Links } from '../../src/components/Links'
+import styles from '../../styles/Home.module.css'
+
+import type { GetStaticPaths, GetStaticProps, NextPage } from 'next'
+
+type Props = {
+ id: string
+}
+
+const SSGPage: NextPage = ({ id }) => {
+ return (
+
+
+
SSG - Example of RecoilHistorySyncJSONNext
+
+
+
+ SSG Page {id}
+
+
+
+
+
+
+
+ )
+}
+
+export default SSGPage
+
+export const getStaticPaths: GetStaticPaths = async () => {
+ return {
+ paths: [
+ { params: { id: '1' } },
+ { params: { id: '2' } },
+ { params: { id: '3' } },
+ ],
+ fallback: false,
+ }
+}
+
+export const getStaticProps: GetStaticProps = async ({
+ params,
+}) => {
+ if (params?.id === undefined) throw new Error('`params.id` is undefined.')
+
+ return {
+ props: {
+ id: params?.id,
+ },
+ }
+}
diff --git a/examples/history-sync-transit/pages/ssr/[id].tsx b/examples/history-sync-transit/pages/ssr/[id].tsx
new file mode 100644
index 00000000..7872e464
--- /dev/null
+++ b/examples/history-sync-transit/pages/ssr/[id].tsx
@@ -0,0 +1,46 @@
+import Head from 'next/head'
+
+import { Counter } from '../../src/components/Counter'
+import { Links } from '../../src/components/Links'
+import { Textfield } from '../../src/components/Textfield'
+import styles from '../../styles/Home.module.css'
+
+import type { GetServerSideProps, NextPage } from 'next'
+
+type Props = {
+ id: string
+}
+
+const SSRPage: NextPage = ({ id }) => {
+ return (
+
+
+
SSR - Example of RecoilHistorySyncJSONNext
+
+
+
+ SSR Page {id}
+
+
+
+
+
+
+
+ )
+}
+
+export default SSRPage
+
+export const getServerSideProps: GetServerSideProps<
+ Props,
+ { id: string }
+> = async ({ params }) => {
+ if (params?.id === undefined) throw new Error('`params.id` is undefined.')
+
+ return {
+ props: {
+ id: params?.id,
+ },
+ }
+}
diff --git a/examples/history-sync-transit/public/favicon.ico b/examples/history-sync-transit/public/favicon.ico
new file mode 100755
index 00000000..718d6fea
Binary files /dev/null and b/examples/history-sync-transit/public/favicon.ico differ
diff --git a/examples/history-sync-transit/src/components/Counter/index.module.css b/examples/history-sync-transit/src/components/Counter/index.module.css
new file mode 100644
index 00000000..17570eef
--- /dev/null
+++ b/examples/history-sync-transit/src/components/Counter/index.module.css
@@ -0,0 +1,5 @@
+.wrapper {
+ display: flex;
+ justify-content: space-between;
+ width: 200px;
+}
diff --git a/examples/history-sync-transit/src/components/Counter/index.tsx b/examples/history-sync-transit/src/components/Counter/index.tsx
new file mode 100644
index 00000000..65f62e7c
--- /dev/null
+++ b/examples/history-sync-transit/src/components/Counter/index.tsx
@@ -0,0 +1,32 @@
+import { number } from '@recoiljs/refine'
+import { useRecoilState } from 'recoil'
+import { syncEffect } from 'recoil-sync'
+import { atomFamilyWithInitialValue } from 'recoil-sync-next'
+
+import styles from './index.module.css'
+
+export const counter = atomFamilyWithInitialValue({
+ key: 'counterState',
+ effects: [syncEffect({ refine: number() })],
+})
+
+export type Props = {
+ name: string
+ initialValue: number
+}
+
+export const Counter: React.FC = ({ name, initialValue }) => {
+ const [count, setCount] = useRecoilState(counter(name, initialValue))
+
+ return (
+
+
+ count[{name}]: {count}
+
+
+
+
+
+
+ )
+}
diff --git a/examples/history-sync-transit/src/components/Links/index.tsx b/examples/history-sync-transit/src/components/Links/index.tsx
new file mode 100644
index 00000000..8b00cd31
--- /dev/null
+++ b/examples/history-sync-transit/src/components/Links/index.tsx
@@ -0,0 +1,44 @@
+import Link from 'next/link'
+
+export const Links: React.FC = () => {
+ return (
+
+ - Top
+ -
+
+
+ - SSR
+ -
+
+ -
+ SSR 1
+
+ -
+ SSR 2
+
+ -
+ SSR 3
+
+
+
+ - SSG
+ -
+
+ -
+ SSG 1
+
+ -
+ SSG 2
+
+ -
+ SSG 3
+
+
+
+
+ )
+}
diff --git a/examples/history-sync-transit/src/components/Textfield/index.module.css b/examples/history-sync-transit/src/components/Textfield/index.module.css
new file mode 100644
index 00000000..0888644f
--- /dev/null
+++ b/examples/history-sync-transit/src/components/Textfield/index.module.css
@@ -0,0 +1,3 @@
+.wrapper {
+ width: 200px;
+}
diff --git a/examples/history-sync-transit/src/components/Textfield/index.tsx b/examples/history-sync-transit/src/components/Textfield/index.tsx
new file mode 100644
index 00000000..3c94c2ad
--- /dev/null
+++ b/examples/history-sync-transit/src/components/Textfield/index.tsx
@@ -0,0 +1,21 @@
+import { string } from '@recoiljs/refine'
+import { atom, useRecoilState } from 'recoil'
+import { syncEffect } from 'recoil-sync'
+
+import styles from './index.module.css'
+
+export const textState = atom({
+ key: 'textState',
+ default: '',
+ effects: [syncEffect({ refine: string() })],
+})
+
+export const Textfield: React.FC = () => {
+ const [text, setText] = useRecoilState(textState)
+
+ return (
+
+ setText(e.currentTarget.value)} />
+
+ )
+}
diff --git a/examples/history-sync-transit/styles/Home.module.css b/examples/history-sync-transit/styles/Home.module.css
new file mode 100755
index 00000000..bb284bbf
--- /dev/null
+++ b/examples/history-sync-transit/styles/Home.module.css
@@ -0,0 +1,17 @@
+.container {
+ padding: 0 2rem;
+}
+
+.main {
+ min-height: 100vh;
+ min-width: 700px;
+ padding: 4rem 0;
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+}
+
+.link {
+ color: blue;
+ text-decoration: underline;
+}
diff --git a/examples/history-sync-transit/styles/globals.css b/examples/history-sync-transit/styles/globals.css
new file mode 100755
index 00000000..83faa13c
--- /dev/null
+++ b/examples/history-sync-transit/styles/globals.css
@@ -0,0 +1,16 @@
+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;
+}
+
+a {
+ color: blue;
+ text-decoration: underline;
+}
+
+* {
+ box-sizing: border-box;
+}
diff --git a/examples/history-sync-transit/tsconfig.json b/examples/history-sync-transit/tsconfig.json
new file mode 100755
index 00000000..921df2f2
--- /dev/null
+++ b/examples/history-sync-transit/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "compilerOptions": {
+ "target": "es2018",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "incremental": true
+ },
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
+ "exclude": ["node_modules"]
+}