{"id":22489819,"url":"https://github.com/graphql-editor/graphql-ssg","last_synced_at":"2025-08-02T22:31:24.168Z","repository":{"id":57253652,"uuid":"355589764","full_name":"graphql-editor/graphql-ssg","owner":"graphql-editor","description":"GraphQL data based Static Site Generator.","archived":true,"fork":false,"pushed_at":"2021-08-19T14:01:59.000Z","size":460,"stargazers_count":30,"open_issues_count":5,"forks_count":0,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-11-19T05:26:50.843Z","etag":null,"topics":["esmodules","graphql","javascript","ssg","static","static-site-generation","static-site-generator"],"latest_commit_sha":null,"homepage":"https://graphqlssg.com","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/graphql-editor.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-04-07T15:12:02.000Z","updated_at":"2023-08-15T14:33:52.000Z","dependencies_parsed_at":"2022-08-31T22:10:15.022Z","dependency_job_id":null,"html_url":"https://github.com/graphql-editor/graphql-ssg","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphql-editor%2Fgraphql-ssg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphql-editor%2Fgraphql-ssg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphql-editor%2Fgraphql-ssg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/graphql-editor%2Fgraphql-ssg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/graphql-editor","download_url":"https://codeload.github.com/graphql-editor/graphql-ssg/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228500500,"owners_count":17930079,"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":["esmodules","graphql","javascript","ssg","static","static-site-generation","static-site-generator"],"created_at":"2024-12-06T17:20:51.136Z","updated_at":"2024-12-06T17:23:15.160Z","avatar_url":"https://github.com/graphql-editor.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# GraphQL SSG\n\n[![NPM Version](https://img.shields.io/npm/v/graphql-ssg.svg?style=flat)]()\n![Build](https://github.com/graphql-editor/graphql-ssg/actions/workflows/release.yml/badge.svg)\n\nIt is the missing ingredient of Web Components architecture. Simple bundler for GraphQL based website using esmodules. What makes it unique? It uses browser for bundling (not node). Remember in ESModules you can use URL imports and relative imports. You can also provide importmap for other imports\n\n## Installation\n\nInstall globally\n\n```sh\nnpm i -g graphql-ssg\n```\n\n## How to use\n\nInit a new project. This will create `graphql-ssg.json` in current directory. You don't need a `package.json` but you can add one for type completions.\n\n```sh\ngraphql-ssg --init .\n```\n\nSet up config.\n\n```json\n{\n  \"graphql\": {\n    \"pokemon\": {\n      \"url\": \"https://graphql-pokemon2.vercel.app/\"\n    }\n  },\n  \"in\": \"./pages\",\n  \"out\": \"./out\",\n  \"websocketPort\": 1414,\n  \"port\": 8080\n}\n```\n\nSo you need to provide your schema url ( you can declare multiple schemas ) ,in and out dirs for graphql-ssg\n\nYou can also add headers if needed:\n\n```json\n{\n  \"graphql\": {\n    \"pokemon\": {\n      \"url\": \"https://graphql-pokemon2.vercel.app/\",\n      \"headers\": {\n        \"Authorization\": \"Bearer MyToken\"\n      }\n    }\n  },\n  \"in\": \"./pages\",\n  \"out\": \"./out\",\n  \"websocketPort\": 1414,\n  \"port\": 8080\n}\n```\n\nWatch\n\n```sh\ngraphql-ssg\n```\n\nBuild\n\n```sh\ngraphql-ssg --build\n```\n\n## How it works?\n\n### File must contain export default\n\nString returned in contained in file export default is generated via SSG phase.\n\n```js\nimport { html } from './ssg/basic.js';\nexport default () =\u003e {\n  return html`\n    \u003cdiv\u003eHello world\u003c/div\u003e\n  `;\n};\n```\n\nTo have syntax coloring in html pleas install appropriate litelement extension for your IDE.\n\n### Config\n\nConfig file can be generated or created manually. It should contain all the following values.\n\n```json\n{\n  \"graphql\": {\n    \"feature-mole\": {\n      \"url\": \"https://faker.graphqleditor.com/explore-projects/feature-mole/graphql\"\n    }\n  },\n  \"in\": \"./pages\",\n  \"out\": \"./out\",\n  \"websocketPort\": 1416,\n  \"port\": 8082\n}\n```\n\n#### Typescript\n\nTurn on typescript support URL imports also works here. Of course you can still import relative modules.\n\n```json\n{\n  \"graphql\": {\n    \"feature-mole\": {\n      \"url\": \"https://faker.graphqleditor.com/explore-projects/feature-mole/graphql\"\n    }\n  },\n  \"in\": \"./pages\",\n  \"out\": \"./out\",\n  \"websocketPort\": 1416,\n  \"port\": 8082,\n  \"mode\": \"typescript\"\n}\n```\n\n#### Config Injection\n\nConfig file is injected and typed. It is available only inside `export default` and `export const head` function to prevent leaking of secrets.\n\nUsage in JS example:\n\n```js\nconst graphQLClient = Chain(ssg.config.HOST, {\n  headers: {\n    Authorization: `Bearer ${ssg.config.TOKEN}`,\n  },\n});\n```\n\n### Environment variables\n\nEnvironment variables must be put side by side to `graphql-ssg.json` in `.env` file.It is available only inside `export default` and `export const head` .\n\nUsage in JS example:\n\n```js\nconst graphQLClient = Chain(ssg.env.HOST, {\n  headers: {\n    Authorization: `Bearer ${ssg.env.TOKEN}`,\n  },\n});\n```\n\nIt is available only inside `export default` and `export const head` function to prevent leaking of secrets.\n\n### Injected built in helper code syntax functions\n\nGraphQL SSG comes with generated library\n\n#### Chain\n\nWorks like fetch to GraphQL, where you need to provide host and/or options to receive fully Autocompleted client for schema url from your config.\n\n```js\nimport { Chain } from './ssg/main-schema/index.js';\nconst graphQLClient = Chain(ssg.config.graphql['main-schema'].url);\n\nconst response = await graphQLClient.query({ people: true });\n```\n\n#### html\n\nIt doesnt transform html in any way, but gives you syntax coloring\n\n```js\nimport { html } from './ssg/basic.js';\nconst ADiv = html`\n  \u003cdiv\u003eHello world\u003c/div\u003e\n`;\n```\n\n#### md\n\nIt renders markdown using remarkable renderer so it is transformed to html.\n\n```js\nimport { md } from './ssg/md.js';\nconst MarkdownContent = md`\n# Title of my Story\n\nblah blah blah blah blah blah\n\n## How to read it?\n`;\n```\n\n#### head\n\n```js\nimport { html } from './ssg/basic.js';\nexport const head = () =\u003e html`\u003ctitle\u003eHello world!\u003c/div\u003e`;\n```\n\n#### data, hydrate\n\nData function is used for so called data hydration in JSX frameworks and others also. It is used for Static Site rendered websites to be able to consume the data and work on client side. So you need to handle both data and hydrate functions yourself so they can be executed on output script.\n\n```tsx\n// Create your app\nexport const data = async () =\u003e {\n  const Fetch = Chain(ssg.config.graphql.pokemon.url, {\n    headers: {\n      'Content-Type': 'application/json',\n    },\n  });\n  return Fetch.query({\n    pokemons: [\n      { first: 151 },\n      {\n        number: true,\n        name: true,\n        image: true,\n        types: true,\n        resistant: true,\n        weaknesses: true,\n      },\n    ],\n  });\n};\n\ntype DataType = ReturnType\u003ctypeof data\u003e extends Promise\u003cinfer R\u003e ? R : never;\n\nexport const hydrate = async (staticData: DataType) =\u003e\n  ReactDOM.hydrate(\u003cPokemonApp response={staticData} /\u003e, document.body);\n\nexport default async (staticData: DataType) =\u003e {\n  const renderBody = document.createElement('div');\n  ReactDOM.render(\u003cPokemonApp response={staticData} /\u003e, renderBody);\n  return renderBody.innerHTML;\n};\n```\n\n#### pages\n\nIf you export pages function you can generate multiple pages per one file. This is useful for example for single blog post page. It takes\n\n```tsx\nexport const data = async () =\u003e {\n  const Fetch = Chain(ssg.config.graphql.pokemon.url, {\n    headers: {\n      'Content-Type': 'application/json',\n    },\n  });\n  return Fetch.query({\n    pokemons: [\n      { first: 5 },\n      {\n        number: true,\n        name: true,\n        image: true,\n        types: true,\n        resistant: true,\n        weaknesses: true,\n      },\n    ],\n  });\n};\n\ntype DataType = ReturnType\u003ctypeof data\u003e extends Promise\u003cinfer R\u003e ? R : never;\n\nexport const pages = (staticData: DataType) =\u003e {\n  return staticData.pokemons?.map((p) =\u003e {\n    const renderBody = document.createElement('div');\n    ReactDOM.render(\u003cPokemonApp {...p} /\u003e, renderBody);\n    return {\n      slug: p.name?.split(' ')[0],\n      body: renderBody.innerHTML,\n      data: p,\n      head: html`\n        \u003ctitle\u003e${p.name || ''}\u003c/title\u003e\n        \u003clink href=\"../index.css\" rel=\"stylesheet\" type=\"text/css\" /\u003e\n      `,\n    };\n  });\n};\n```\n\n## Assets\n\nYou can use them as normally.\n\n## Type Streaming\n\nFor example: If you use url that begins with `https://cdn.skypack.dev` in your import. It will try to fetch typings from skypack and save them in typings folder referencing to jsconfig. This should provide typings for example in VSCode.\n\n## Roadmap\n\n- [x] Add esbuild\n- [x] Add TS support\n- [x] Add intelligent .d.ts autocompletion for imported es modules\n- [x] Add image supports\n- [x] Generate tsconfig\n- [x] Relative imports\n- [x] Allow head modification\n- [x] Pass env to browser\n- [x] Provide a way to inject config\n- [x] TSConfig generation for included declarations to work\n- [x] Make zeus configurable and importable file\n- [ ] Clear error handling with line numbers\n- [x] split utility functions css,html,md from zeus\n- [x] allow to auto-zeus multiple schemas\n- [x] Types from url streaming\n- [x] JSX, TSX support\n- [ ] Provide verbose info levels\n- [ ] Create docs deployable to pages\n- [ ] Resolve imports with no extension\n- [ ] generate ts functions for ts projects\n- [ ] catch esbuild transform errors\n- [x] support files exporting multiple static pages\n- [ ] Add possibility to override html tag\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgraphql-editor%2Fgraphql-ssg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgraphql-editor%2Fgraphql-ssg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgraphql-editor%2Fgraphql-ssg/lists"}