{"id":30000993,"url":"https://github.com/OverflowCat/astro-typst","last_synced_at":"2025-08-05T06:04:24.721Z","repository":{"id":251187321,"uuid":"836661120","full_name":"OverflowCat/astro-typst","owner":"OverflowCat","description":"All-in-one Typst integration for Astro","archived":false,"fork":false,"pushed_at":"2025-07-31T23:47:24.000Z","size":568,"stargazers_count":85,"open_issues_count":12,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-08-01T04:51:20.061Z","etag":null,"topics":["astro","typst"],"latest_commit_sha":null,"homepage":"https://typst.overflow.cat","language":"Astro","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OverflowCat.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-08-01T09:45:50.000Z","updated_at":"2025-08-01T00:41:56.000Z","dependencies_parsed_at":"2024-08-01T11:25:09.907Z","dependency_job_id":"a6e39a9b-dccd-478c-846e-f55aea7458c6","html_url":"https://github.com/OverflowCat/astro-typst","commit_stats":{"total_commits":16,"total_committers":1,"mean_commits":16.0,"dds":0.0,"last_synced_commit":"ec09e8dbc19a5edabb91fd5e7dc9abaa15120188"},"previous_names":["overflowcat/astro-typst"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/OverflowCat/astro-typst","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OverflowCat%2Fastro-typst","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OverflowCat%2Fastro-typst/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OverflowCat%2Fastro-typst/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OverflowCat%2Fastro-typst/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OverflowCat","download_url":"https://codeload.github.com/OverflowCat/astro-typst/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OverflowCat%2Fastro-typst/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268844815,"owners_count":24316055,"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","status":"online","status_checked_at":"2025-08-05T02:00:12.334Z","response_time":2576,"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":["astro","typst"],"created_at":"2025-08-05T06:01:40.903Z","updated_at":"2025-08-05T06:04:24.703Z","avatar_url":"https://github.com/OverflowCat.png","language":"Astro","funding_links":[],"categories":["Astro"],"sub_categories":[],"readme":"# `astro-typst`\n\n![NPM Version](https://img.shields.io/npm/v/astro-typst?style=for-the-badge)\n\u003ca href='https://typst.app/' target=\"_blank\"\u003e\u003cimg alt='Supported Typst version: 0.13' src='https://img.shields.io/badge/Typst_0.13-100000?style=for-the-badge\u0026logo=Typst\u0026logoColor=30bdc1\u0026labelColor=FFFFFF\u0026color=30BDB2' /\u003e\n\nAn Astro [Integration](https://astro.build/integrations/) that lets you render [Typst](https://github.com/typst/typst) within [Astro](https://github.com/withastro/astro) based on [typst.ts](https://github.com/Myriad-Dreamin/typst.ts). We have made you an Astro-ish wrapper that you cannot refuse!\n\n\u003cimg src=\"https://repository-images.githubusercontent.com/836661120/7c4046ff-03be-45dc-a28b-393d23dcd614\" alt=\"Demo\" width=\"500\" /\u003e\n\n## Features\n\n- [x] Import packages in [Typst Universe](https://typst.app/universe/)\n- [x] `import` / `include` / `read` files or resources\n- [x] Use system fonts\n- [x] Selectable, clickable text layer\n- [x] Set scale\n- [x] Static SVGs without JavaScript\n- [x] Static HTML output without JavaScript\n- [x] [Content collections](https://docs.astro.build/en/guides/content-collections/)\n- [x] Write frontmatter directly in `.typ`\n- [x] Jump between internal links ([client JS](https://github.com/OverflowCat/astro-typst/issues/6) needed)\n- [x] Pass JS data to typst using the component ([how](https://github.com/OverflowCat/astro-typst/issues/2))\n- [ ] Pass data from typst to JS\n- [x] Render to `\u003cimg\u003e` with `src=` emitted SVG assets (#20)\n- [ ] Responsive SVGs\n- [ ] [Paged output](https://github.com/OverflowCat/astro-typst/issues/3)\n- [x] Add font files or blobs (`fontArgs` in config)\n\n## Installation\n\n```bash\nnpm install astro-typst\n# or\npnpm add astro-typst\n# or\nyarn add astro-typst\n```\n\n## Usage\n\nCheckout the [live demo](https://typst.overflow.cat)!\n\n### As an integration\n\n```js\n// astro.config.mjs\nimport { typst } from 'astro-typst';\n\n... // other imports\n\nexport default defineConfig({\n  integrations: [\n    /** other integrations */...,\n    typst({\n      options: {\n        remPx: 14,\n      },\n      target: (id: string) =\u003e {\n        console.debug(`Detecting ${id}`);\n        if (id.endsWith('.html.typ') || id.includes('/html/'))\n          return \"html\";\n        return \"svg\";\n      },\n      // === \u003cimg src=\"xxx.svg\"\u003e instead of inlined \u003csvg\u003e ===\n      // emitSvg: true,\n      // emitSvgDir: \".astro/typst\"\n      // === Add non-system fonts here ===\n      // fontArgs: [\n      //   { fontPaths: ['/system/fonts', '/user/fonts'] },\n      //   { fontBlobs: [customFontBuffer] }\n      // ],\n    }),\n  ],\n});\n```\n\nThe `target` function determines which mode a file will render in. The default is:\n\n```\n*.html.typ =\u003e html export\n *.svg.typ =\u003e  svg export\n**/html/** =\u003e html export\n **/svg/** =\u003e  svg export\n```\n\nThen you can use `.typ` files just like anything else in Astro: render directly by router, or import in another file.\n\nExample:\n\n```mdx\nimport Paper from \"./_test.typ\";\n\n\u003cPaper /\u003e\n```\n\nForce HTML output:\n\n```mdx\nimport Paper from \"./_test.typ?html\";\n\n\u003cPaper /\u003e\n```\n\nForce SVG output:\n```mdx\nimport Paper from \"./_test.typ?svg\";\n\n\u003cPaper /\u003e\n```\n\nYou can also emit SVG to standalone files on build mode. Modify the `emitSvg` and `emitSvgDir` option in the config. (Added in v0.10)\n\n### As a component\n\nTo use the component, you need to manually install a dependency to avoid SSR errors:\n\n```\nnpm install @myriaddreamin/typst-ts-node-compiler\n# or\npnpm add @myriaddreamin/typst-ts-node-compiler\n# or\nyarn add @myriaddreamin/typst-ts-node-compiler\n```\n\nand add this to your `/astro.config.(t|j)s/`:\n\n```diff\nexport default defineConfig({\n  ...,\n  vite: {\n    ssr: {\n-      external: [...],\n+      external: [..., \"@myriaddreamin/typst-ts-node-compiler\"],\n    },\n    ...,\n  },\n  ...,\n});\n```\n\nThen, you can pass either one of `code | src | input` to the component:\n\n```astro\n---\nimport { Typst } from \"astro-typst/src/components\";\nconst code = `\n#set page(margin: 1em)\n#let typst  = {\n  text(font: \"Linux Libertine\", weight: \"semibold\", fill: eastern)[typst]\n}\n#show \"Typst\": typst\n\n== Typst: Compose paper faster\n\n$ cases(\ndot(x) = A x + B u = mat(delim: \"[\", 0, 0, dots.h.c, 0, - a_n; 1, 0, dots.h.c, 0, - a_(n - 1); 0, 1, dots.h.c, 0, - a_(n - 2); dots.v, dots.v, dots.down, dots.v, dots.v; 0, 0, dots.h.c, 1, - a_1) x + mat(delim: \"[\", b_n; b_(n - 1); b_(n - 2); dots.v; b_1) u,\n\ny = C x = mat(delim: \"[\", 0, 0, dots.h.c, 1) x\n) $\n\n#set text(font: (\"Garamond\", \"Noto Serif CJK SC\"))\n\n#import \"@preview/tablem:0.1.0\": tablem\n\n#tablem[\n  | *English* | *German* | *Chinese* | *Japanese* |\n  | --------- | -------- | --------- | ---------- |\n  | Cat       | Katze    | 猫        | 猫         |\n  | Fish      | Fisch    | 鱼        | 魚         |\n]\n`;\n---\n\n\u003cTypst code={code} /\u003e\n\n\u003c!-- or HTML output: --\u003e\n\n\u003cTypst code={code} target=\"html\" /\u003e\n```\n\n### In content collections\n\nSee [demo](/src/content/).\n\n#### Frontmatter\n\n\u003e [`metadata`](https://typst.app/docs/reference/introspection/metadata/) exposes a value to the query system without producing visible content.\n\nAttach a label `frontmatter` to the metadata declaration:\n\n```typ\n#let desc = [$oo$ fun with `math`]\n#metadata(\n  (\n    title: \"Test page\",\n    author: \"Neko\",\n    desc: desc,\n    date:  datetime(\n      year: 2024,\n      month: 8,\n      day: 7,\n    ),\n  )\n)\u003cfrontmatter\u003e\n```\n\nyields\n\n```json\n{\n  \"title\": \"Test page\",\n  \"author\": \"Neko\",\n  \"desc\": {\n    \"children\": [\n      {\n        \"block\": false,\n        \"body\": {\n          \"func\": \"text\",\n          \"text\": \"∞\"\n        },\n        \"func\": \"equation\"\n      },\n      { \"func\": \"space\" },\n      { \"func\": \"text\", \"text\": \"fun with\" },\n      { \"func\": \"space\" },\n      {\n        \"block\": false,\n        \"func\": \"raw\",\n        \"text\": \"math\"\n      }\n    ],\n    \"func\": \"sequence\"\n  },\n  \"date\": \"datetime(year: 2024, month: 8, day: 7)\"\n}\n```\n\nThis is only a demo for how various typst types will be converted;\nyou don't need to use all of them.\n\n### Internal links\n\nImport `Jump.astro`, or add the following snippet to your page\n\n\u003cdetails\u003e\n\u003csummary\u003e Snippet \u003c/summary\u003e\n\n```js\n/**\nCopyright 2025 Myriad-Dreamin\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\nfunction findAncestor(el, cls) {\n  while ((el = el.parentElement) \u0026\u0026 !el.classList.contains(cls));\n  return el;\n}\n\nwindow.handleTypstLocation = function (elem, page, x, y) {\n  const docRoot = findAncestor(elem, 'typst-doc');\n  const children = docRoot.children;\n  let nthPage = 0;\n  for (let i = 0; i \u003c children.length; i++) {\n    if (children[i].tagName === 'g') {\n      nthPage++;\n    }\n    if (nthPage == page) {\n      const page = children[i];\n      const dataWidth = page.getAttribute('data-page-width');\n      const dataHeight = page.getAttribute('data-page-height');\n      const rect = page.getBoundingClientRect();\n      const xOffsetInner = Math.max(0, x / dataWidth - 0.05) * rect.width;\n      const yOffsetInner = Math.max(0, y / dataHeight - 0.05) * rect.height;\n      const xOffsetInnerFix = (x / dataWidth) * rect.width - xOffsetInner;\n      const yOffsetInnerFix = (y / dataHeight) * rect.height - yOffsetInner;\n\n      const docRoot = document.body || document.firstElementChild;\n      const basePos = docRoot.getBoundingClientRect();\n\n      const xOffset = rect.left - basePos.left + xOffsetInner;\n      const yOffset = rect.top - basePos.top + yOffsetInner;\n      const left = xOffset + xOffsetInnerFix;\n      const top = yOffset + yOffsetInnerFix;\n\n      console.log('scrolling to', xOffset, yOffset, left, top);\n\n      window.scrollTo(xOffset, yOffset);\n      return;\n    }\n  }\n};\n```\n\n\u003c/details\u003e\n\n## Development\n\n### Playground\n\n```bash\npnpm tsc -w\n# in another terminal\npnpm dev\n```\n\n### Build package\n\n```bash\npnpm compile\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FOverflowCat%2Fastro-typst","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FOverflowCat%2Fastro-typst","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FOverflowCat%2Fastro-typst/lists"}