{"id":25936723,"url":"https://github.com/namgunggeon/react-hydratable","last_synced_at":"2025-03-04T02:45:25.879Z","repository":{"id":123147551,"uuid":"467457042","full_name":"NamGungGeon/react-hydratable","owner":"NamGungGeon","description":"hold-on DOM structure for improving React SEO","archived":false,"fork":false,"pushed_at":"2024-04-28T14:36:07.000Z","size":54,"stargazers_count":19,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"release","last_synced_at":"2025-03-04T02:45:21.781Z","etag":null,"topics":["csr","javascript","react","seo-optimization"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/NamGungGeon.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,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-08T10:04:21.000Z","updated_at":"2025-02-14T15:04:33.000Z","dependencies_parsed_at":"2024-04-28T15:25:21.908Z","dependency_job_id":"eda9ef29-6a96-40f7-8113-0639f2272eed","html_url":"https://github.com/NamGungGeon/react-hydratable","commit_stats":{"total_commits":21,"total_committers":1,"mean_commits":21.0,"dds":0.0,"last_synced_commit":"8465cfb0a43f0d75edb00a102d1aa11f56e83594"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NamGungGeon%2Freact-hydratable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NamGungGeon%2Freact-hydratable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NamGungGeon%2Freact-hydratable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NamGungGeon%2Freact-hydratable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NamGungGeon","download_url":"https://codeload.github.com/NamGungGeon/react-hydratable/tar.gz/refs/heads/release","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241773255,"owners_count":20018064,"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":["csr","javascript","react","seo-optimization"],"created_at":"2025-03-04T02:45:25.009Z","updated_at":"2025-03-04T02:45:25.874Z","avatar_url":"https://github.com/NamGungGeon.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# react-hydratable\n\n`react-hydratable` is nodejs module for improving SEO performance of SPA project.\n\nIn React, `npm run build` create build outputs.\n\nBut `index.html` has just blank body. Because in SPA framework(ex: react) javascript file will render html elements.\n\nIn SPA with CSR, SEO performance is very poor. Of course, SSR framework(ex: nextjs) can solve this problem, but some project cannot be moved from CSR to SSR because of various problems.\n\nIn this case, `react-hydratable` can be very powerful weapon.\n\n`react-hydratable` just create simple http webserver based on your SPA build output, and starting crawling html after executing javascript. Finally crawled html data is saved to appropriate build path.\n\nSo, After executing `react-hydratable`, `index.html` is prerendered.\n\nIt has fullfilled body.\n\nNow every search bot(that cannot execute javascript, just read html file) can collect your website informations!!\n\n## Installation\n\n1. install module from npm\n   `npm install -D react-hydratable`\n\n2. setup\n   Go to your project root and open `src/index.js`\n\n   ```javascript\n   //react 16, 17\n   import React from 'react';\n   import { hydrate, render } from 'react-dom';\n\n   // ...\n\n   //update here\n   //optional render/hydrate\n   if (rootElement.hasChildNodes()) {\n     hydrate(element, rootElement);\n   } else {\n     render(element, rootElement);\n   }\n   ```\n   ```javascript\n   //react 18\n    import React from \"react\";\n    import { createRoot, hydrateRoot } from \"react-dom/client\";\n\n\n    if (rootElement.hasChildNodes()){\n      hydrateRoot(rootElement, element);\n    } else {\n      const root = createRoot(rootElement);\n      root.render(element, rootElement);\n    }\n   ```\n\nIf user access crawled page, `???/html` has been filled body. So browser need not break all DOM and re-render all elements.\n\nBrowser can use already-made-DOM objects. `hydrate()/hydrateRoot()` function support this.\n\nThat's all! `react-hydratable` is ready!!\n\n## Start Crawling\n\n`react-hydratable` use `/build` files.\n\nAdd `react-hydratable` script to your `package.json`.\n\n`package.json`\n\n```json\n{\n  \"...\": \"...\",\n  \"scripts\": {\n    \"...\": \"...\",\n    //add new scripts\n    \"postbuild\": \"react-hydratable\"\n  },\n  \"...\": \"...\"\n}\n```\n\nThis script(postbuild) means that run `react-hydratable` after `build` script is finished.\n\nWhat a so simple usage.\n\nYou just type `npm run build` to terminal.\n\n`react-hydratable` will be executed automatically after building project.\n\n## Preview prerendered pages\n\nDo you wonder your prerendered pages are working correctly?\n\n`react-hydratable` support \"preview mode\".\n\n// package.json\n\n```json\n{\n  \"...\": \"...\",\n  \"scripts\": {\n    \"...\": \"...\",\n    //add new scripts\n    \"preview\": \"react-hydratable --preview\"\n  },\n  \"...\": \"...\"\n}\n```\n\nNow, you can check your prerendered pages after type `npm run preview` to terminal.\n\n## (Optional) Customize configurations\n\nreact-hydratable has default config.\n\n```json\n{\n  \"webroot\": \"./build\",\n  \"host\": \"http://localhost\",\n  \"port\": 3000,\n  \"crawlingUrls\": [\"/\"],\n  \"delay\": 1500,\n  \"htmlPrefix\": \"\u003c!DOCTYPE html\u003e\"\n}\n```\n\nIf you want customize settings(ex: I want to crawl html about more url), create `hydratable.config.json` to project root(same level with `package.json`).\n\nExplaination of all configurations is at page bottom.\n\n#### Set crawling targets(urls)\n\n```json\n//hydratable.config.json\n{\n  \"crawlingUrls\": [\"/\", \"/copyrights\"]\n}\n```\n\nAs this configuration, `react-hydratable` start crawling '/' and '/copyrights'.\n\nAnd also, create new html file(`build/copyrights/index.html`) and refresh default index.html file(`build/index.html`).\n\nDefault `crawlingUrls` value is `['/']` (only crawling `/build/index.html` and refresh it)\n\n**Keep in mind \"all type of crawlingUrl must be text/html\"**\n\n**Other Content-Type is not accepted**\n\n### Set crawling delay\n\nIn crawling phase, load html and wait for `delay`.\n\nAfter finishing loading, maybe `html` is not perfecttly loadded.\n\nFor example, if target page uses `ajax`, `html` is not perfect before `ajax` is finished.\n\nSo `react-hydratable` solve this problem as waiting some time.\n\nDefault waiting time is `1500`ms.\n\nIf you want increase delay from 1500ms to 2000ms, override `delay` property.\n\n`hydratable.config.json`\n\n```json\n{\n  \"delay\": 2000\n}\n```\n\nNow `react-hydratable` wait 2000 ms after loading page.\n\n### Set multi-page crawling\n\nIf you have a lot of page that will be crawling(crawlingUrls), it takes many time.\n\nIn this case, you can use multi-page crawling.\n\nDefault value is 1, this means one page(one window) is used to crawl your `crawlingUrls`.\n\nYou can increase page(window) count as increase `pageCount` value.\n\nBut if `pageCount` gets too big, server may be slow and also crawling result be wrong.\n\nRecommend set between 1~4.\n\n### All configurations\n\n```json\n{\n  \"webroot\": \"/your_project_root/build\",\n  \"host\": \"http://localhost\",\n  \"port\": 3000,\n  \"crawlingUrls\": [\"/\"],\n  \"delay\": 1500,\n  \"userAgent\": \"react-hydratable\",\n  \"htmlPrefix\": \"\u003c!DOCTYPE html\u003e\",\n  \"pageCount\": 1,\n  \"retryCount\": 1,\n}\n```\n\n`webroot`: react build directory path\n\n`host`: webserver host (http only)\n\n`port`: webserver port\n\n`crawlingUrls`: crawling target url list\n\n`delay`: wait time(ms) after page is loaded\n\n`userAgent`: crawler user-agent (request header)\n\n`htmlPrefix`: prefix string that is added crawling result (if blank, `\u003c!DOCTYPE html\u003e` is not included)\n\n`pageCount`: multi-page crawling is support. if you increase this value, crawling speed is up, but may stress to server.\n\n`retryCount`: if crawling is fail, do retry as retryCount times automatically.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnamgunggeon%2Freact-hydratable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnamgunggeon%2Freact-hydratable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnamgunggeon%2Freact-hydratable/lists"}