{"id":13567880,"url":"https://github.com/egoist/presite","last_synced_at":"2025-04-04T13:08:56.057Z","repository":{"id":23147075,"uuid":"98275755","full_name":"egoist/presite","owner":"egoist","description":"A static site generator based on Puppeteer.","archived":false,"fork":false,"pushed_at":"2023-08-03T07:05:14.000Z","size":756,"stargazers_count":334,"open_issues_count":26,"forks_count":19,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-28T12:04:56.174Z","etag":null,"topics":["prerender","spa"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/egoist.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-07-25T07:09:10.000Z","updated_at":"2025-02-28T09:11:24.000Z","dependencies_parsed_at":"2024-01-13T20:59:31.446Z","dependency_job_id":null,"html_url":"https://github.com/egoist/presite","commit_stats":{"total_commits":75,"total_committers":8,"mean_commits":9.375,"dds":"0.29333333333333333","last_synced_commit":"79803cb99a7d0b278ae2297d137b4648c8adbda8"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egoist%2Fpresite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egoist%2Fpresite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egoist%2Fpresite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/egoist%2Fpresite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/egoist","download_url":"https://codeload.github.com/egoist/presite/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247180788,"owners_count":20897289,"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":["prerender","spa"],"created_at":"2024-08-01T13:02:47.702Z","updated_at":"2025-04-04T13:08:56.037Z","avatar_url":"https://github.com/egoist.png","language":"TypeScript","funding_links":["https://github.com/sponsors/egoist"],"categories":["TypeScript"],"sub_categories":[],"readme":"# presite\n\n[![NPM version](https://img.shields.io/npm/v/presite.svg?style=flat)](https://npmjs.com/package/presite) [![NPM downloads](https://img.shields.io/npm/dm/presite.svg?style=flat)](https://npmjs.com/package/presite) [![donate](https://img.shields.io/badge/$-donate-ff69b4.svg?maxAge=2592000\u0026style=flat)](https://github.com/sponsors/egoist)\n\n## Why Presite?\n\nPresite is an alternative to static site generators like Gatsby, Next.js and Nuxt.js etc, the difference is that it uses [Puppeteer](https://pptr.dev) to prerender websites instead of relying on server-side rendering.\n\n## Install\n\n```bash\nnpm i -g presite\n```\n\n**Note that Presite relies on Chrome (or Chromium) browser on your machine, so you need to ensure it's installed before running Presite**.\n\n## Usage\n\n```bash\npresite ./path/to/your/site\n```\n\nPresite is supposed to work with existing single-page applications, first you use something like Create React App, Vue CLI, Parcel or Vite to create a production build of your app, then use Presite to pre-render the website to static HTML files.\n\nPre-rendered website will be generated into `.presite` folder.\n\n## Examples\n\n\u003cdetails\u003e\u003csummary\u003ewith Create React App\u003c/summary\u003e\n\n```diff\n{\n  \"scripts\": {\n-    \"build\": \"react-scripts build\"\n+    \"build\": \"react-scripts build \u0026\u0026 presite ./build\"\n  }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003ewith Vue CLI\u003c/summary\u003e\n\n```diff\n{\n  \"scripts\": {\n-    \"build\": \"vue-cli-service build\"\n+    \"build\": \"vue-cli-service build \u0026\u0026 presite ./dist\"\n  }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003ewith Poi\u003c/summary\u003e\n\n```diff\n{\n  \"scripts\": {\n-    \"build\": \"poi build\"\n+    \"build\": \"poi build \u0026\u0026 presite ./dist\"\n  }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003ewith Vite\u003c/summary\u003e\n\n```diff\n{\n  \"scripts\": {\n-    \"build\": \"vite build\"\n+    \"build\": \"vite build \u0026\u0026 presite ./dist\"\n  }\n}\n```\n\n\u003c/details\u003e\n\n**That's it, Presite prerender all pages of your website without any configuration!**\n\nRun `presite --help` for all CLI flags.\n\n## Non-HTML pages\n\nPresite also supports rendering non-HTML pages like XML or JSON pages, simply create files ending with `.xml.js` or `.json.js`, let's say you have a `feed.json.js`:\n\n```js\nimport { createJSONFeed } from './somewhere/create-json-feed'\n\nexport default async () =\u003e {\n  const posts = await fetch('/api/my-posts').then((res) =\u003e res.json())\n  return createJSONFeed(posts)\n}\n```\n\nYou can export a function that resolves to a string or JSON object, then Presite will output this page as `feed.json`.\n\nThese pages are evaluated in browser in a `\u003cscript type=\"module\"\u003e` tag, so you can use the `import` keyword.\n\n## Using `presite.config.js`\n\nMany CLI flags can be stored in a configuration file, it's totaly optional but if you need one, it's there for you.\n\nBesides `presite.config.js`, you can also use `presite.config.json` or the `presite` key in `package.json`.\n\n### Set routes that needs prerender\n\nIf some of your pages are not referenced by other pages, you can manually specify them here:\n\n```js\nmodule.exports = {\n  routes: ['/', '/about'],\n}\n```\n\n**Note that in most cases you won't need this option, Presite automatically find all same-site `\u003ca\u003e` elements on the pages and prerender all of them.**\n\nIf you want to fetch routes asynchronously, use `async/await`:\n\n```js\nmodule.exports = {\n  async routes() {\n    const routes = await fetchRoutesFromSomeWhere()\n    return routes\n  },\n}\n```\n\n### Wait\n\nWait specific ms or dom element to appear:\n\n```js\nmodule.exports = {\n  wait: 3000,\n  // Or wait for an element to appear\n  // wait: '#comments'\n}\n```\n\n### Maunally set ready state\n\nInstead of using `wait` you can manually tell when the app is ready:\n\n```js\nmodule.exports = {\n  manually: true,\n}\n```\n\nThen you can call `window.snapshot` in your app when its contents are ready:\n\n```js\nwindow.snapshot \u0026\u0026 window.snapshot()\n```\n\nTo use a custom global variable name, set it to a string instead:\n\n```js\nmodule.exports = {\n  manually: `__my_snapshot__`,\n}\n```\n\nNow you should call `window.__my_snapshot__()` instead.\n\n### Access Puppeteer browser page\n\nAccess the [`page`](https://pptr.dev/#?product=Puppeteer\u0026version=v5.2.1\u0026show=api-class-page) instance, for example, to expose some functions from Node.js to browser:\n\n```js\nmodule.exports = {\n  async onBrowserPage(page) {\n    await page.exposeFunction('md5', (content) =\u003e md5(content))\n  },\n}\n```\n\n### Filter out link to be crawled\n\nTo prevent link (from `\u003ca\u003e` elements) to be crawled, you could use the `linkFilter` option:\n\n```js\nmodule.exports = {\n  // Returns `true` to keep, `false` otherwise\n  linkFilter(url) {\n    // Ignore URLs ending with .xml\n    return !url.endsWith('.xml')\n  },\n}\n```\n\n### Source directory\n\nThis is the same as using CLI `presite ./path/to/your/spa`:\n\n```js\nmodule.exports = {\n  baseDir: './path/to/your/spa',\n}\n```\n\n### Output directory\n\nBy default it outputs to `.presite` folder in current directory.\n\n```js\nmodule.exports = {\n  outDir: '.presite',\n}\n```\n\n## CLI options\n\nRun `presite --help`.\n\n## Contributing\n\n1. Fork it!\n2. Create your feature branch: `git checkout -b my-new-feature`\n3. Commit your changes: `git commit -am 'Add some feature'`\n4. Push to the branch: `git push origin my-new-feature`\n5. Submit a pull request :D\n\n## Author\n\n**presite** © [egoist](https://github.com/egoist), Released under the [MIT](./LICENSE) License.\u003cbr\u003e\nAuthored and maintained by egoist with help from contributors ([list](https://github.com/egoist/presite/contributors)).\n\n\u003e [Website](https://egoist.sh) · GitHub [@egoist](https://github.com/egoist) · Twitter [@\\_egoistlily](https://twitter.com/_egoistlily)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fegoist%2Fpresite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fegoist%2Fpresite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fegoist%2Fpresite/lists"}