{"id":18545693,"url":"https://github.com/jakubkulhan/caddy-chrome","last_synced_at":"2026-04-27T08:32:24.567Z","repository":{"id":247727677,"uuid":"826334515","full_name":"jakubkulhan/caddy-chrome","owner":"jakubkulhan","description":"Caddy middleware to server-side render Javascript applications using Chrome","archived":false,"fork":false,"pushed_at":"2024-08-13T14:05:55.000Z","size":1807,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-15T06:39:57.515Z","etag":null,"topics":["caddy","caddy-plugin","server-side-rendering","webcomponents"],"latest_commit_sha":null,"homepage":"","language":"Go","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/jakubkulhan.png","metadata":{"files":{"readme":"README.md","changelog":null,"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,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-07-09T14:02:55.000Z","updated_at":"2025-03-24T15:44:18.000Z","dependencies_parsed_at":"2024-08-13T17:09:24.821Z","dependency_job_id":null,"html_url":"https://github.com/jakubkulhan/caddy-chrome","commit_stats":null,"previous_names":["jakubkulhan/caddy-chrome"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jakubkulhan/caddy-chrome","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jakubkulhan%2Fcaddy-chrome","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jakubkulhan%2Fcaddy-chrome/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jakubkulhan%2Fcaddy-chrome/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jakubkulhan%2Fcaddy-chrome/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jakubkulhan","download_url":"https://codeload.github.com/jakubkulhan/caddy-chrome/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jakubkulhan%2Fcaddy-chrome/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32329463,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T23:26:28.701Z","status":"online","status_checked_at":"2026-04-27T02:00:06.769Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["caddy","caddy-plugin","server-side-rendering","webcomponents"],"created_at":"2024-11-06T20:21:43.492Z","updated_at":"2026-04-27T08:32:24.538Z","avatar_url":"https://github.com/jakubkulhan.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Caddy Chrome\n\n\u003e Caddy middleware to server-side render Javascript applications using Chrome\n\n## Server-side rendering\n\nThe middleware takes an HTML response from the upstream handlers, loads it up in Chrome on the server, and intercepts requests from the browser. Requests to the same host are routed internally in the webserver, possibly loading files, but also speaking to other applications e.g. by a reverse proxy. After the page is fully loaded, DOM is serialized to an HTML and then returned back to the client as the response.\n\n```mermaid\nsequenceDiagram\n    actor Client\n    participant Caddy\n    participant Chrome\n    Client-\u003e\u003eCaddy: GET /index.html\n    activate Caddy\n    Caddy--\u003e\u003eCaddy: Load index.html file\n    Caddy-\u003e\u003eChrome: Navigate to /index.html\n    activate Chrome\n    Chrome-\u003e\u003eCaddy: GET /index.html\n    Caddy-\u003e\u003eChrome: Respond with the index.html\n    Chrome-\u003e\u003eCaddy: GET /script.js\n    Caddy--\u003e\u003eCaddy: Internal request for /script.js\n    Caddy-\u003e\u003eChrome: Respond with /script.js response\n    Caddy--\u003eChrome: ...sub-requests...\n    Chrome-\u003e\u003eCaddy: HTML-serialized DOM of the page\n    deactivate Chrome\n    Caddy-\u003e\u003eClient: Respond with the Chrome-rendered page\n    deactivate Caddy\n```\n\n## Asynchronous components\n\nThe middleware handles asynchronous components on the page using [`pending-task` protocol](https://github.com/webcomponents-cg/community-protocols/blob/main/proposals/pending-task.md). For an example, see [pending_task.html](testdata/pending_task.html).\n\n## Resource hints\n\nBecause Chrome on the server loads up the page the same way as the browser on the client, we can know what resources the page needs. Therefore, to speed up loading on the client side, the middleware adds [preload](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/preload) and [preconnect](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/preconnect) resource hints as Link HTTP headers.\n\n## Configuration\n\n```caddy\nchrome {\n    timeout 10s\n    mime_types text/html\n    \n    exec /usr/bin/google-chrome --headless\n    exec_no_default_flags /usr/bin/google-chrome --headless\n    url http://localhost:9222/\n    \n    fullfill_hosts localhost app.example.com api.example.com\n    continue_hosts cdn.example.com static.example.com\n}\n```\n\n- `timeout` - maximum time to wait for Chrome to render the page, default is `10s`.\n- `mime_types` - list of MIME types to render, default is `text/html`.\n- Browser (only one of these):\n  - `exec` - executes the local browser binary by given path, if the first argument starts with a dash (`-`), the binary is automatically found in the path and all the arguments are treated as additional flags on top of the [default flags](https://pkg.go.dev/github.com/chromedp/chromedp#pkg-variables)\n  - `exec_no_default_flags` - the same as `exec` but without the default flags\n  - `url` - URL to the debugging protocol endpoint of a remote browser instance\n- `fullfill_hosts` - a list of hosts to issue as internal requests through the webserver, there's automatically the host of the original request\n- `continue_hosts` - a list of hosts to let Chrome do the regular network requests\n\n## Build\n\n```shell\nxcaddy build --with github.com/jakubkulhan/caddy-chrome\n```\n\n## License\n\nLicensed under MIT license. See [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjakubkulhan%2Fcaddy-chrome","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjakubkulhan%2Fcaddy-chrome","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjakubkulhan%2Fcaddy-chrome/lists"}