@fyit/crouton-assets
v0.1.0
Published
Asset management layer extending nuxt-crouton for centralized media library
Maintainers
Readme
@fyit/crouton-assets
Centralized asset management system for Nuxt Crouton. Provides a full-featured media library with team-based ownership, metadata tracking, and browsing capabilities.
Features
- 📸 Centralized Asset Library - Single source of truth for all uploads
- 🎯 Asset Picker UI - Browse and select existing assets with thumbnails
- 📊 Rich Metadata - Track filename, size, MIME type, alt text, upload date
- 👥 Team-Based - Assets are scoped to teams/organizations
- 🔍 Search & Filter - Find assets quickly
- ♿ Accessibility - Alt text support for all images
- 🌍 i18n Ready - Translatable alt text (with nuxt-crouton-i18n)
Installation
pnpm add @fyit/crouton-assetsSetup
1. Install the package
pnpm add @fyit/crouton-assets2. Configure Nuxt
Add to your nuxt.config.ts:
export default defineNuxtConfig({
extends: [
'@fyit/crouton',
'@fyit/crouton-assets' // Add assets layer
],
hub: {
blob: true // Required: Enable NuxtHub blob storage
}
})3. Generate the assets collection
Use the collection generator to create the assets collection in your project:
crouton-generate core assets --fields-file=node_modules/@fyit/crouton-assets/assets-schema.json --dialect=sqliteOr create your own schema and generate:
// assets-schema.json
{
"id": { "type": "string", "meta": { "primaryKey": true } },
"teamId": { "type": "string", "refTarget": "organisations", "meta": { "required": true } },
"userId": { "type": "string", "refTarget": "users", "meta": { "required": true } },
"filename": { "type": "string", "meta": { "required": true } },
"pathname": { "type": "string", "meta": { "required": true } },
"contentType": { "type": "string" },
"size": { "type": "number" },
"alt": { "type": "string" },
"uploadedAt": { "type": "date" },
"updatedBy": { "type": "string", "refTarget": "users" }
}crouton-generate core assets --fields-file=assets-schema.json --dialect=sqliteThis creates layers/core/collections/assets/ in your project with all the CRUD endpoints and components.
Usage
In Forms (Schema Definition)
Use the asset picker to reference assets by ID:
{
"imageId": {
"type": "string",
"refTarget": "assets",
"meta": {
"component": "CroutonAssetsPicker",
"label": "Featured Image"
}
}
}Direct Upload Component
For simple uploads without the asset library:
<template>
<CroutonImageUpload
v-model="imageUrl"
@file-selected="handleUpload"
/>
</template>
<script setup>
const imageUrl = ref('')
const handleUpload = async (file) => {
if (!file) return
const formData = new FormData()
formData.append('image', file)
const pathname = await $fetch('/api/upload-image', {
method: 'POST',
body: formData
})
imageUrl.value = `/images/${pathname}`
}
</script>Asset Picker Component
Browse and select from existing assets:
<template>
<CroutonAssetsPicker v-model="selectedAssetId" />
</template>
<script setup>
const selectedAssetId = ref('')
</script>Architecture
Base Package (nuxt-crouton)
Provides core upload infrastructure:
POST /api/upload-image- Upload to blob storageGET /images/[pathname]- Serve from blob storageCroutonImageUpload- Simple file picker componentCroutonAvatarUpload- Avatar variant component
Assets Package (this package) - Provides Tools
The package provides reusable components and composables:
CroutonAssetsPicker- Browse/select assets UI componentCroutonAssetsUploader- Upload + metadata form componentuseAssetUpload()- Composable for programmatic uploadsassets-schema.json- Reference schema for generation
Your Project - Generated Collection
You generate the actual assets collection using crouton-generate:
layers/core/collections/assets/- Generated collection- Form.vue, List.vue - CRUD UI
- API endpoints - GET/POST/PATCH/DELETE at
/api/teams/[id]/assets - Database schema - Assets table with all metadata
- Composable - useCoreAssets() with validation
The package tools (CroutonAssetsPicker, CroutonAssetsUploader) work WITH your generated collection.
Simple vs. Full Approach
Simple (Base Package Only)
// Store URL directly in your table
{
"imageUrl": { "type": "string" }
}Full Asset Management (With This Package)
// Store asset ID, get all metadata
{
"imageId": {
"type": "string",
"refTarget": "assets",
"meta": { "component": "CroutonAssetsPicker" }
}
}Database Schema
The assets collection includes:
id- Unique identifierteamId- Team/organization ownershipuserId- User who uploadedfilename- Original filenamepathname- Blob storage pathcontentType- MIME typesize- File size in bytesalt- Alt text (translatable)uploadedAt- Upload timestampcreatedAt/updatedAt- Metadata timestampsupdatedBy- Last modifier
Requirements
- Nuxt 4+
- @fyit/crouton
- @nuxthub/core with blob storage enabled
- @vueuse/core
License
MIT © FYIT
