{"id":13756536,"url":"https://github.com/effector/nextjs-legacy","last_synced_at":"2025-05-10T03:32:13.392Z","repository":{"id":57146060,"uuid":"242770403","full_name":"effector/nextjs-legacy","owner":"effector","description":"☄️ Effector wrappers for Next.js","archived":true,"fork":false,"pushed_at":"2023-04-07T10:59:58.000Z","size":423,"stargazers_count":42,"open_issues_count":3,"forks_count":6,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-04-29T18:22:44.999Z","etag":null,"topics":["effector","nextjs","react"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/effector.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2020-02-24T15:22:54.000Z","updated_at":"2025-04-11T21:59:07.000Z","dependencies_parsed_at":"2023-09-29T12:45:53.653Z","dependency_job_id":null,"html_url":"https://github.com/effector/nextjs-legacy","commit_stats":{"total_commits":51,"total_committers":5,"mean_commits":10.2,"dds":0.1568627450980392,"last_synced_commit":"e99c135c7211f46752d4850fc532115d9773aa8f"},"previous_names":["effector/nextjs","weyheyhey/effector-next"],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/effector%2Fnextjs-legacy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/effector%2Fnextjs-legacy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/effector%2Fnextjs-legacy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/effector%2Fnextjs-legacy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/effector","download_url":"https://codeload.github.com/effector/nextjs-legacy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252922325,"owners_count":21825633,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["effector","nextjs","react"],"created_at":"2024-08-03T11:00:46.408Z","updated_at":"2025-05-10T03:32:13.075Z","avatar_url":"https://github.com/effector.png","language":"TypeScript","funding_links":[],"categories":["Packages"],"sub_categories":[],"readme":"# Effector Next\n\n\u003e Note: we recommend using [`@effector/next`](https://github.com/effector/next) package.\n\nA HOCs that brings Effector and Next.js together\n\n[![npm version](https://badge.fury.io/js/effector-next.svg)](https://www.npmjs.com/package/effector-next)\n\n## Installation\n\n```bash\nnpm install effector-next\n```\n\nor yarn\n\n```bash\nyarn add effector-next\n```\n\n**effector-next** requires `effector`, `effector-react` to be installed\n\n**effector/babel-plugin** is necessary if you do not want to manually name the units\n\n## Settings\n\n1. To load the initial state on the server, you must attach `withFork` wrapper to your `_document` component\n\n   \u003cdetails\u003e\n   \u003csummary\u003epages/_document.jsx\u003c/summary\u003e\n\n   ```jsx\n   import Document from \"next/document\";\n   import { withFork } from \"effector-next\";\n\n   const enhance = withFork({ debug: false });\n\n   export default enhance(Document);\n   ```\n\n   \u003c/details\u003e\n\n2. To get the initial state on the client and drop it into the application, you must attach `withHydrate` wrapper to your `_app` component\n\n   \u003cdetails\u003e\n   \u003csummary\u003epages/_app.jsx\u003c/summary\u003e\n\n   ```jsx\n   import { withHydrate } from \"effector-next\";\n   import App from \"next/app\";\n\n   const enhance = withHydrate();\n\n   export default enhance(App);\n   ```\n\n   \u003c/details\u003e\n\n3. To bind events/stores on the server to the scope, add aliases from `effector-react` to `effector-react/ssr` in `next.config.js`\n\n   \u003cdetails\u003e\n   \u003csummary\u003enext.config.js\u003c/summary\u003e\n\n   ```js\n   const { withEffectorReactAliases } = require(\"effector-next/tools\");\n\n   const enhance = withEffectorReactAliases();\n\n   module.exports = enhance({});\n   ```\n\n   \u003c/details\u003e\n\n4. Replace imports from `\"effector\"` to `\"effector-next\"`\n\n   ```diff\n   - import { createEvent, forward } from \"effector\"\n   + import { createEvent, forward } from \"effector-next\"\n   ```\n\n5. Connect the `effector/babel-plugin`\n\n   \u003cdetails\u003e\n   \u003csummary\u003e.babelrc\u003c/summary\u003e\n\n   ```json\n   {\n     \"presets\": [\"next/babel\"],\n     \"plugins\": [\"effector/babel-plugin\"]\n   }\n   ```\n\n   If you are using `effector` version \u003e 21.3.0, you also need to configure the babel plugin:\n\n   ```json\n   {\n     \"presets\": [\"next/babel\"],\n     \"plugins\": [\"effector/babel-plugin\", { \"importName\": [\"effector-next\"] }]\n   }\n   ```\n\n   \u003c/details\u003e\n\n6. Configure what event will be triggered when the page is requested from the server using `withStart`\n\n   \u003cdetails\u003e\n   \u003csummary\u003epages/index.js\u003c/summary\u003e\n\n   ```jsx\n   import React from \"react\";\n   import { withStart } from \"effector-next\";\n   import { useStore } from \"effector-react\";\n\n   import { pageLoaded } from \"../model\";\n\n   const enhance = withStart(pageLoaded);\n\n   function HomePage() {\n     return (\n       \u003cdiv\u003e\n         \u003ch1\u003eHello World\u003c/h1\u003e\n       \u003c/div\u003e\n     );\n   }\n\n   export default enhance(HomePage);\n   ```\n\n   \u003c/details\u003e\n\n### Example\n\n1. Declare our model\n\n   \u003cdetails\u003e\n   \u003csummary\u003emodels/index.js\u003c/summary\u003e\n\n   ```jsx\n   import { forward, createEvent, createStore, createEffect } from \"effector-next\";\n\n   export const pageLoaded = createEvent();\n   export const buttonClicked = createEvent();\n\n   const effect = createEffect({\n     handler(name) {\n       return Promise.resolve({ name });\n     },\n   });\n\n   export const $data = createStore(null);\n\n   $data.on(effect.done, (_, { result }) =\u003e result);\n\n   forward({\n     from: pageLoaded.map(() =\u003e \"nameFromPageLoaded\"),\n     to: effect,\n   });\n\n   forward({\n     from: buttonClicked.map(() =\u003e \"nameFromButtonClicked\"),\n     to: effect,\n   });\n   ```\n\n   \u003c/details\u003e\n\n2. Connect the page to the store (all units must be wrapped in hooks - this is necessary in order to associate units with scope on the server)\n\n   \u003cdetails\u003e\n   \u003csummary\u003epages/index.jsx\u003c/summary\u003e\n\n   ```jsx\n   import React from \"react\";\n   import { useStore, useEvent } from \"effector-react\";\n\n   import { $data, buttonClicked } from \"../models\";\n\n   export default function HomePage() {\n     const data = useStore($data);\n     const handleClick = useEvent(buttonClicked);\n\n     return (\n       \u003cdiv\u003e\n         \u003ch1\u003eHomePage\u003c/h1\u003e\n         \u003ch2\u003eStore state: {JSON.stringify({ data })}\u003c/h2\u003e\n         \u003cbutton onClick={handleClick}\u003eclick to change store state\u003c/button\u003e\n       \u003c/div\u003e\n     );\n   }\n   ```\n\n   \u003c/details\u003e\n\n3. Bind an event that will be called on the server when the page is requested\n\n   \u003cdetails\u003e\n   \u003csummary\u003epages/index.jsx\u003c/summary\u003e\n\n   ```diff\n   import React from \"react\";\n   import { useStore, useEvent } from \"effector-react\";\n   +import { withStart } from \"effector-next\";\n\n   -import { $data, buttonClicked } from \"../models\";\n   +import { $data, pageLoaded, buttonClicked } from \"../models\";\n\n   +const enhance = withStart(pageLoaded);\n\n   -export default function HomePage() {\n   +function HomePage() {\n     const data = useStore($data);\n     const handleClick = useEvent(buttonClicked);\n\n     return (\n       \u003cdiv\u003e\n         \u003ch1\u003eHomePage\u003c/h1\u003e\n         \u003ch2\u003eStore state: {JSON.stringify({ data })}\u003c/h2\u003e\n         \u003cbutton onClick={handleClick}\u003eclick to change store state\u003c/button\u003e\n       \u003c/div\u003e\n     );\n   }\n\n   +export default enhance(HomePage);\n   ```\n\n   \u003c/details\u003e\n\n## Configuration\n\nThe `withFork` accepts a config object as a parameter:\n\n- `debug` (optional, boolean) : enable debug logging\n- `serializeIgnore` (optional, array) : stores whose values ​​should not be sent to the client after serialization\n\n## Server payload\n\nWhen the unit passed to `withStart` is called, the object will be passed as a payload:\n\n- `req` : incoming request\n- `res` : serever response\n- `cookies` : parsed cookies\n- `pathname` : path section of `URL`\n- `query` : query string section of `URL` parsed as an object.\n\n## Release process\n\n1. Check out the [draft release](https://github.com/effector/nextjs/releases).\n1. All PRs should have correct labels and useful titles. You can [review available labels here](https://github.com/effector/nextjs/blob/master/.github/release-drafter.yml).\n1. Update labels for PRs and titles, next [manually run the release drafter action](https://github.com/effector/nextjs/actions/workflows/release-drafter.yml) to regenerate the draft release.\n1. Review the new version and press \"Publish\"\n1. If required check \"Create discussion for this release\"\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feffector%2Fnextjs-legacy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feffector%2Fnextjs-legacy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feffector%2Fnextjs-legacy/lists"}