{"id":17041418,"url":"https://github.com/davestewart/nuxt-content-assets","last_synced_at":"2025-04-12T20:43:07.960Z","repository":{"id":150361613,"uuid":"623003508","full_name":"davestewart/nuxt-content-assets","owner":"davestewart","description":"Enable locally-located assets in Nuxt Content","archived":false,"fork":false,"pushed_at":"2024-10-06T05:03:32.000Z","size":3953,"stargazers_count":120,"open_issues_count":22,"forks_count":8,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-03T23:09:37.903Z","etag":null,"topics":["cms","content","nuxt"],"latest_commit_sha":null,"homepage":"https://npmjs.com/package/nuxt-content-assets","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/davestewart.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2023-04-03T13:55:10.000Z","updated_at":"2025-03-31T15:15:44.000Z","dependencies_parsed_at":"2023-11-10T08:48:45.682Z","dependency_job_id":"6147a8b7-105c-49e1-98c9-d9820a0dd938","html_url":"https://github.com/davestewart/nuxt-content-assets","commit_stats":null,"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davestewart%2Fnuxt-content-assets","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davestewart%2Fnuxt-content-assets/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davestewart%2Fnuxt-content-assets/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davestewart%2Fnuxt-content-assets/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/davestewart","download_url":"https://codeload.github.com/davestewart/nuxt-content-assets/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248631675,"owners_count":21136555,"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":["cms","content","nuxt"],"created_at":"2024-10-14T09:12:22.490Z","updated_at":"2025-04-12T20:43:07.928Z","avatar_url":"https://github.com/davestewart.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# Nuxt Content Assets\n\n[![npm version][npm-version-src]][npm-version-href]\n[![npm downloads][npm-downloads-src]][npm-downloads-href]\n[![License][license-src]][license-href]\n[![Nuxt][nuxt-src]][nuxt-href]\n\n\u003e Enable locally-located assets in Nuxt Content\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/davestewart/nuxt-content-assets/main/playground/public/splash.png\" alt=\"Nuxt Content Assets logo\"\u003e\n\u003c/p\u003e\n\n## Overview\n\nNuxt Content Assets enables locally-located assets in [Nuxt Content](https://content.nuxtjs.org/):\n\n```\n+- content\n    +- posts\n        +- 2023-01-01\n            +- index.md\n            +- media\n                +- featured.png\n                +- mountains.jpg\n                +- seaside.mp4\n```\n\nIn your documents, reference assets with relative paths:\n\n```markdown\n---\ntitle: Summer Holiday\nfeatured: media/featured.png\n---\n\nI loved being in the mountains.\n\n![mountains](media/mountains.png)\n\nAlmost as much as being in the sea!\n\n:video{src=\"media/seaside.mp4\"}\n```\n\nAt build time the module [collates and serves](#how-it-works) assets and content together.\n\n### Features\n\nBuilt on top of [Nuxt Content](https://github.com/nuxt/content/) and compatible with any Nuxt Content project or theme, including [Docus](https://github.com/nuxt-themes/docus).\n\nUser experience:\n\n- co-locate assets with content files\n- reference assets using relative paths\n- supports any format (image, video, doc)\n\nDeveloper experience:\n\n- works with tags and custom components\n- works in markdown and frontmatter\n- file watching and asset live-reload\n- image size injection\n- zero config\n\n## Playground\n\nTo test the module before installing, you can try out the Nuxt Content Assets playground.  \n\nTo clone and run locally:\n\n```bash\ngit clone https://github.com/davestewart/nuxt-content-assets.git\ncd nuxt-content-assets\nnpm install \u0026\u0026 npm install --prefix ./playground\nnpm run dev\n```\n\nThen open the playground in your browser at \u003ca href=\"http://localhost:3000\" target=\"_blank\"\u003elocalhost:3000\u003c/a\u003e.\n\nTo run the playground online, visit:\n\n- https://stackblitz.com/github/davestewart/nuxt-content-assets?file=playground%2Fapp.vue\n\nTo browse the playground folder:\n\n- https://github.com/davestewart/nuxt-content-assets/tree/main/playground\n\n## Setup\n\nInstall the dependency:\n\n```bash\nnpm install nuxt-content-assets\n```\n\nConfigure `nuxt.config.ts`:\n\n```js\nexport default defineNuxtConfig({\n  modules: [\n    'nuxt-content-assets', // make sure to add before content!\n    '@nuxt/content',\n  ]\n})\n```\n\nRun the dev server or build and local assets should now be served alongside markdown content.\n\n## Usage\n\n### Overview\n\nUse relative paths anywhere within your documents:\n\n```md\nImages\n![image](image.jpg)\n\nLinks\n[link](docs/article.txt)\n\nElements / components\n:video{src=\"media/video.mp4\"}\n\nHTML\n\u003ciframe src=\"media/example.html\" /\u003e\n```\n\nRelative paths can be defined in frontmatter – as long as they are the only value:\n\n```md\n---\ntitle: Portfolio\nimages:\n  - assets/image-1.jpg\n  - assets/image-2.jpg\n  - assets/image-3.jpg\n---\n```\n\nThese values can then be passed to components:\n\n```markdown\n:image-gallery{:data=\"images\"}\n```\n\nSee the playground for [markup](playground/content/advanced/gallery.md) and [component](playground/components/content/ContentGallery.vue) examples.\n\n### Live reload\n\nIn development, the module watches for asset additions, moves and deletes, and will update the browser live.\n\nIf you delete an asset, it will be greyed out in the browser until you replace the file or modify the path to it.\n\nIf you edit an image, video, embed or iframe source, the content will update immediately, which is useful if you're looking to get that design just right!\n\n\u003e [!NOTE]\n\u003e Live reload does not currently work with Nuxt Image (see Issue [#77](https://github.com/davestewart/nuxt-content-assets/issues/77)).\n\u003e \n\u003e If you need to iterate on image design, consider disabling Nuxt Image in development.\n\n### Image sizing\n\n#### HTML\n\nThe module can pass image size hints to generated `\u003cimg\u003e` tags:\n\n```html\n\u003c!-- imageSize: 'style' --\u003e\n\u003cimg src=\"/image.jpg\" style=\"aspect-ratio:640/480\"\u003e\n\n\u003c!-- imageSize: 'attrs' --\u003e\n\u003cimg src=\"/image.jpg\" width=\"640\" height=\"480\"\u003e\n```\n\nTurning this on prevents content jumps as your page loads.\n\n\u003e [!CAUTION]\n\u003e Don't use `imageSize: 'src'` in conjunction with Nuxt Image as it prevents the IPX module from correctly serving images, which causes static site generation to fail \n\n#### Prose components\n\nIf you use [ProseImg](https://content.nuxtjs.org/api/components/prose) components, you can [hook into](playground/components/temp/ProseImg.vue) image size hints via the `$attrs` property:\n\n```vue\n\u003ctemplate\u003e\n  \u003cspan class=\"image\"\u003e\n    \u003cimg :src=\"$attrs.src\" :width=\"$attrs.width\" :height=\"$attrs.height\" /\u003e\n  \u003c/span\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nexport default {\n  inheritAttrs: false\n}\n\u003c/script\u003e\n```\n\n#### Frontmatter\n\nIf you pass [frontmatter](playground/content/advanced/gallery.md) to [custom components](playground/components/content/ContentImage.vue) set `imageSize` to `'src'` to encode values in `src`:\n\n```\n:image-content{:src=\"image\"}\n```\n\nThe component will receive the size information as a query string which you can extract and apply:\n\n```html\n\u003cimg class=\"image-content\" src=\"/image.jpg?width=640\u0026height=480\"\u003e\n```\n\nSee playground component [here](playground/components/content/ContentImage.vue).\n\n### Nuxt Image\n\n[Nuxt Image](https://image.nuxtjs.org/) is supported by adding Nuxt Content Asset's cache folder as a Nuxt Layer:\n\n```ts\n// nuxt.config.ts\nexport default defineNuxtConfig({\n  extends: [\n    'node_modules/nuxt-content-assets/cache',\n  ],\n}\n```\n\nTo serve all images as Nuxt Image images, create a `ProseImg` component like so:\n\n```vue\n\u003c!-- components/content/ProseImg.vue --\u003e\n\u003ctemplate\u003e\n  \u003cnuxt-img /\u003e\n\u003c/template\u003e\n```\n\nSee the playground folder for both the [global](playground/components/temp/ProseImg.vue) and a [per image](playground/components/content/NuxtImg.ts) solution.\n\n## Configuration\n\nThe module has the following options:\n\n```ts\n// nuxt.config.ts\nexport default defineNuxtConfig({\n  contentAssets: {    \n    // inject image size hints into the rendered html\n    imageSize: 'style',\n    \n    // treat these extensions as content\n    contentExtensions: 'mdx? csv ya?ml json',\n    \n    // output debug messages\n    debug: false,\n  }\n})\n```\n\n### Image size\n\n\u003e [!Note]\n\u003e\n\u003e Since `v1.4.1` image size hints are now opt-in. This was done to maximise compatibiility with Nuxt Image.\n\nYou can add one _or more_ image size hints to the generated images:\n\n```ts\n{\n  imageSize: 'style attrs src'\n}\n```\n\nPick from the following switches:\n\n| Switch    | What it does                                                       |\n|-----------|--------------------------------------------------------------------|\n| `'style'` | Adds `style=\"aspect-ratio:...\"` to any `\u003cimg\u003e` tag                 |\n| `'attrs'` | Adds `width` and `height` attributes to any `\u003cimg\u003e` tag            |\n| `'src'`   | Adds `?width=...\u0026height=...` to `src` attribute (frontmatter only) |\n\nNote: if you add *only* `attrs`, include the following CSS in your app:\n\n```css\nimg {\n  max-width: 100%;\n  height: auto;\n}\n```\n\n### Content extensions\n\n\u003e [!NOTE]\n\u003e Generally, you shouldn't need to touch this setting\n\nThis setting tells Nuxt Content to ignore anything that is **not** one of the supported content types:\n\n```\nmdx? csv ya?ml json\n```\n\nThis way, you can use any **other** file type as an asset, without needing to explicitly configure Nuxt Content's [ignores](https://content.nuxt.com/get-started/configuration#ignores) list.\n\nWithout this, Nuxt Content would warn about unsupported file types: \n\n\u003e [WARN] .jpg files are not supported, \"content:path:to:some-asset.jpg\" falling back to raw content\n\n### Debug\n\nIf you want to see what the module does as it runs, set `debug` to true:\n\n```ts\n{\n  debug: true\n}\n```\n\n## How it works\n\nWhen Nuxt builds, the module scans all content sources for assets, copies them to a temporary layer folder (`nuxt_modules/nuxt-content-assets/cache`), and indexes path and image metadata.\n\nAfter Nuxt Content has run, the parsed content (`.nuxt/content-cache`) is traversed, and both element attributes and frontmatter properties are checked to see if they resolve to the previously-indexed asset paths.\n\nIf they do, then the attribute or property in Nuxt Content's cache is rewritten with the absolute path. If the asset is an image, then the element or metadata is optionally updated with size attributes or a query string.\n\nFinally, Nitro serves the site, and any requests made to the transformed asset paths should be picked up and the *copied* asset served by the browser.\n\nIn development, a watch process propagates asset changes to the cache, updates the asset index, and notifies the browser via web sockets to refresh any loaded images. \n\nIf Nuxt Image is used, the `_ipx/` endpoint serves images directly from the cache's public folder.\n\n## Development\n\nShould you wish to develop the project, you'll work with the following entities:\n\n- [src](./src)\u003cbr\u003eThe module code itself\n- [playground](./playground)\u003cbr\u003eA standalone Nuxt app that reads the live module code\n- [scripts](package.json)\u003cbr\u003eA set of scripts to develop and publish the module\n\n### Setup\n\nTo set up the project, run each of these scripts once:\n\n```bash\n# install dependencies\nnpm install\n\n# copy the cache folder to the playground's node_modules (workaround required in development)\nnpm run dev:setup\n\n# generate types for the module and playground (re-run if you install new packages)\nnpm run dev:prepare\n```\n\n### Development\n\nTo develop the module, utilise the supplied playground app:\n\n```bash\n# compile the module, run and serve the playground\nnpm run dev\n\n# generate the playground\nnpm run dev:generate\n\n# build the playground\nnpm run dev:build\n\n# serve the generated/built playground\nnpm run dev:preview\n```\n\nCheck your code quality using these tools:\n\n```bash\n# lint your code with eslint\nnpm run lint\n\n# runs tests with vitest\nnpm run test\nnpm run test:watch\n```\n\n### Publishing\n\n\u003e [!IMPORTANT]\n\u003e Before publishing, be sure to update the [version](package.json) and [changelog](CHANGELOG.md)!\n\nTo build and publish, run following scripts as required:\n\n```bash\n# lint, test, build, and dry-run publish\nnpm run release:dry\n\n# lint, test, build and publish\nnpm run release\n```\n\n## Maintenance\n\nThis module was created using the Nuxt [Module Builder](https://github.com/nuxt/module-builder) command:\n\n```bash\nnpx nuxi init -t module nuxt-content-assets\n```\n\nThis created the module code from the starter template found here:\n\n- https://github.com/nuxt/starter/tree/module\n\nBoth [Nuxi](https://github.com/nuxt/cli) and the module's dependencies and scripts are updated fairly regularly, so from time to time this module may need to be updated to keep in sync. So far, this has meant just updating the dependencies and scripts, which are found in the starter template code mentioned above.\n\nNote that the build/release scripts are slightly modified from the originals; build is now separated, and release now doesn't use [changelogen](https://github.com/unjs/changelogen), or automatically add tags and push to GitHub.\n\n\u003c!-- Badges --\u003e\n[npm-version-src]: https://img.shields.io/npm/v/nuxt-content-assets/latest.svg?style=flat\u0026colorA=18181B\u0026colorB=28CF8D\n[npm-version-href]: https://npmjs.com/package/nuxt-content-assets\n\n[npm-downloads-src]: https://img.shields.io/npm/dm/nuxt-content-assets.svg?style=flat\u0026colorA=18181B\u0026colorB=28CF8D\n[npm-downloads-href]: https://npmjs.com/package/nuxt-content-assets\n\n[license-src]: https://img.shields.io/npm/l/nuxt-content-assets.svg?style=flat\u0026colorA=18181B\u0026colorB=28CF8D\n[license-href]: https://npmjs.com/package/nuxt-content-assets\n\n[nuxt-src]: https://img.shields.io/badge/Nuxt-18181B?logo=nuxt.js\n[nuxt-href]: https://nuxt.com\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavestewart%2Fnuxt-content-assets","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavestewart%2Fnuxt-content-assets","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavestewart%2Fnuxt-content-assets/lists"}