{"id":15296056,"url":"https://github.com/stackbit/nextjs-hot-content-reload","last_synced_at":"2026-01-05T09:07:23.316Z","repository":{"id":57162336,"uuid":"439157681","full_name":"stackbit/nextjs-hot-content-reload","owner":"stackbit","description":"Hot content reload for Next.js dev server","archived":false,"fork":false,"pushed_at":"2022-04-06T12:41:17.000Z","size":199,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-01T15:04:58.425Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/stackbit.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}},"created_at":"2021-12-16T23:49:42.000Z","updated_at":"2022-09-24T00:36:37.000Z","dependencies_parsed_at":"2022-09-04T09:21:19.775Z","dependency_job_id":null,"html_url":"https://github.com/stackbit/nextjs-hot-content-reload","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stackbit%2Fnextjs-hot-content-reload","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stackbit%2Fnextjs-hot-content-reload/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stackbit%2Fnextjs-hot-content-reload/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stackbit%2Fnextjs-hot-content-reload/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stackbit","download_url":"https://codeload.github.com/stackbit/nextjs-hot-content-reload/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245407755,"owners_count":20610232,"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":[],"created_at":"2024-09-30T18:09:06.987Z","updated_at":"2026-01-05T09:07:23.311Z","avatar_url":"https://github.com/stackbit.png","language":"TypeScript","readme":"# Next.js Hot Content Reload\n\nWhen working locally, the \"Hot Content Reload\" lets you \"hot reload\" the props returned by  Next.js `getStaticProps` and `getServerSideProps` methods.\n\nThe idea is similar to Webpack's [Hot Module Replacement](https://webpack.js.org/concepts/hot-module-replacement/). However, instead of watching for code changes and replacing the changed components in the browser, it lets you configure your Next.js site to watch for content changes made in Headless CMS or local files and update the page with the new content without refreshing the browser.\n\n## How to use\n\nThe Hot Content Reload consists of two parts:\n\n1. A server with a websocket exposing the `notifyPropsChanged` function. When you call this function, it sends a websocket event to the client, causing it to reload the props of the currently rendered page.\n2. A high-order component that wraps the page component. It listens to the websocket events sent by the server and reloads the props when such events are received.\n\nTo create the websocket server import the `startHotContentReloadSocketServer` function from the `@stackbit/nextjs-hot-content-reload` package inside your `next.config.js`. Create the socket server by invoking the `startHotContentReloadSocketServer()` function. Make sure to do that when running next.js in development mode. Then call the `socketServer.notifyPropsChanged()` method whenever the props driving your pages are changed. See the following section for examples of when to call this method when working with different headless CMS.\n\n`next.config.js`:\n```javascript\nconst { startHotContentReloadSocketServer } = require('@stackbit/nextjs-hot-content-reload');\n\nif (process.env.NODE_ENV === 'development') {\n    // You can also provide optional options object with custom \"port\", \"namespace\" and \"eventName\"\n    // or leave it empty to use defaults that work with Stackbit preview.\n    const socketServer = startHotContentReloadSocketServer({\n        // port: '...',\n        // namespace: '...',\n        // eventName: '...'\n    });\n\n    // call socketServer.notifyPropsChanged() when content is changed\n    function onContentChange() {\n        socketServer.notifyPropsChanged();\n    }\n}\n\nmodule.exports = {\n    // ... next.js config goes here\n};\n```\n\nNext, wrap your page components with `withHotContentReload` high-order-component to enable hot-content-reload in these pages. By default, `withHotContentReload` sets websocket listener when `process.env.NODE_ENV === 'development'`. If you need to customize the behavior of `withHotContentReload` high-order-component, import the `hotContentReload` factory method and pass it custom options to create your own `withHotContentReload` HOC.\n\n```javascript\nimport { withHotContentReload } from '@stackbit/nextjs-hot-content-reload/hotContentReload';\n\nfunction Page(props) {\n    return (\n        \u003cmain\u003e{props.title}\u003c/main\u003e\n    );\n}\n\nexport default withHotContentReload(Page);\n\nexport function getStaticProps() {\n    // ...\n}\n```\n\n## Examples\n\n### Hot reloading file-system content\n\nAssuming your site's pages render data stored in markdown files, you can use [chokidar](https://www.npmjs.com/package/chokidar) to listen for file changes and call `socketServer.notifyPropsChanged()`:\n\n```javascript\nconst { startHotContentReloadSocketServer } = require('@stackbit/nextjs-hot-content-reload');\nconst chokidar = require('chokidar');\n\nif (process.env.NODE_ENV === 'development') {\n    const socketServer = startHotContentReloadSocketServer();\n\n    function onContentChange(filePath) {\n        socketServer.notifyPropsChanged();\n    }\n\n    const watcher = chokidar.watch('content', {ignoreInitial: true});\n    watcher.on('add', onContentChange);\n    watcher.on('change', onContentChange);\n    watcher.on('unlink', onContentChange);\n}\n```\n\n### Contentful\n\nIf your site uses Contentful as its headless CMS, you can use the `@stackbit/contentful-listener` package. Call the `socketServer.notifyPropsChanged()` when contentful-listener notifies you of a content change:\n\n```javascript\nconst { startHotContentReloadSocketServer } = require('@stackbit/nextjs-hot-content-reload');\nconst { ContentfulListener } = require('@stackbit/contentful-listener');\n\nif (process.env.NODE_ENV === 'development') {\n    const socketServer = startHotContentReloadSocketServer();\n\n    const contentfulListener = new ContentfulListener({\n        spaceId: process.env.CONTENTFUL_SPACE_ID,\n        accessToken: process.env.CONTENTFUL_PREVIEW_API_KEY,\n        environment: 'master',\n        host: 'preview.contentful.com',\n        pollingIntervalMs: 1000,\n        callback: (result: CallbackResponse) =\u003e {\n            socketServer.notifyPropsChanged();\n        }\n    });\n    contentfulListener.start();\n}\n```\n\n### Sanity\n\nIf your site uses Sanity as its headless CMS, you  can use the `@sanity/client` package and its `listen` API and call the `socketServer.notifyPropsChanged()` when Sanity notifies you of change events:\n\n```javascript\nconst { startHotContentReloadSocketServer } = require('@stackbit/nextjs-hot-content-reload');\nconst sanityClient = require('@sanity/client');\n\nif (process.env.NODE_ENV === 'development') {\n    const socketServer = startHotContentReloadSocketServer();\n    const client = sanityClient({\n        projectId: 'your-project-id',\n        dataset: 'dataset-name',\n        apiVersion: '2021-03-25', // use current UTC date - see \"specifying API version\"!\n        token: 'sanity-auth-token', // or leave blank for unauthenticated usage\n        useCdn: false\n    });\n\n    const query = '*[!(_id in path(\"_.**\"))]';\n    const params = {};\n\n    const subscription = client.listen(query, params).subscribe((update) =\u003e {\n        socketServer.notifyPropsChanged();\n    });\n}\n```\n\n## Example Project\n\nYou can find an example Next.js starter project inside the [example](/example) folder.\n\nThere you will find [pages/index.js](example/pages/index.js) file that implements `getStaticProps` method. The `getStaticProps` method loads data from [content/index.yaml](example/content/index.yaml) and returns as props to be consumed by the `Home` component. It also wraps the `Home` component with `hotContentReload` high-order component to setup websocket listener on the client as described before.\n\n```javascript\nfunction Home(props) {\n    // ...\n}\n\nconst withHotContentReload = hotContentReload();\n\nexport default withHotContentReload(Home);\n\nexport function getStaticProps() {\n    const yamlData = fs.readFileSync('content/index.yaml', 'utf-8')\n    const props = yaml.load(yamlData)\n    return {props}\n}\n```\n\nAnd finally, [next.config.js](example/next.config.js) installs a websocket service and a file listener that calls `socketServer.notifyPropsChanged()` when the [content/index.yaml](example/content/index.yaml) file is changed.\n\nTo try it out:\n\n- clone this repo\n- run `npm install` in the root folder\n- run `npm run build` in the root folder\n- run `cd example`\n- run `npm install`\n- run `npm run dev`\n- navigate to http://localhost:3000\n- open the [content/index.yaml](example/content/index.yaml) file and change something\n- the browser will instantly reflect the changes\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstackbit%2Fnextjs-hot-content-reload","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstackbit%2Fnextjs-hot-content-reload","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstackbit%2Fnextjs-hot-content-reload/lists"}