cdnSrc y cdnSrcSet
Paquetes: @tiendana/ngx-core/ui @tiendana/api-types
Directivas para cargar imágenes transformando URLs de S3 al endpoint privado de Tiendana (cdn-public.tiendana.com).
CdnSrcDirective y CdnSrcSetDirective existen en el código fuente de @tiendana/ngx-core, pero no se exportan desde @tiendana/ngx-core/ui (v0.9.0): import { CdnSrcDirective } from '@tiendana/ngx-core/ui' falla. Para cargar imágenes con la API pública usa cfSrc y cfSrcSet. Esta página describe el comportamiento interno de las directivas.
El tipo Attachment proviene de @tiendana/api-types y representa objetos de archivos en la plataforma Tiendana (imágenes, documentos, etc.).
cdnSrc
Directiva para el atributo src de imágenes. Soporta URLs de S3, objetos File, Attachment y preview local.
Características
✅ Transforma URLs de S3 a cdn-public.tiendana.com
✅ Preview local de objetos File vía FileReader
✅ Soporte para tipo Attachment de @tiendana/api-types
✅ Fallback automático en error
API
| Input | Tipo | Descripción |
|---|---|---|
cdnSrc | string | File | Attachment | null | URL, archivo o attachment |
Uso Básico
// URL de S3
<img [cdnSrc]="'s3://bucket/images/logo.svg'" />
// String simple
<img [cdnSrc]="'assets/images/product.jpg'" />
// Attachment object
<img [cdnSrc]="attachment" />
Con File Object
Preview de archivos antes de subir:
@Component({
template: `
<input type="file" (change)="onFileChange($event)">
@if (file()) {
<img [cdnSrc]="file()!" alt="Preview" />
}
`
})
export class FilePreviewComponent {
file = signal<File | null>(null);
onFileChange(event: Event) {
const input = event.target as HTMLInputElement;
if (input.files?.[0]) {
this.file.set(input.files[0]);
}
}
}
cdnSrcSet
Directiva para el atributo srcset en elementos <source>.
API
| Input | Tipo | Descripción |
|---|---|---|
cdnSrcSet | string | Attachment | null | Fuente para srcset |
defaultCdnSrcSet | string | Fallback por defecto |
Uso con Picture
<picture>
<source
[cdnSrcSet]="'s3://bucket/image-large.jpg'"
media="(min-width: 800px)"
/>
<source
[cdnSrcSet]="'s3://bucket/image-small.jpg'"
/>
<img [cdnSrc]="'s3://bucket/image-fallback.jpg'" />
</picture>
Ejemplos Combinados
Gallery Responsive
@Component({
template: `
@for (img of images(); track img.id) {
<picture>
<source
[cdnSrcSet]="img.large"
media="(min-width: 1024px)"
/>
<source
[cdnSrcSet]="img.medium"
media="(min-width: 768px)"
/>
<img [cdnSrc]="img.thumbnail" [alt]="img.alt" />
</picture>
}
`
})
export class GalleryComponent {
images = signal([
{
id: 1,
large: 's3://bucket/product-1-lg.jpg',
medium: 's3://bucket/product-1-md.jpg',
thumbnail: 's3://bucket/product-1-sm.jpg',
alt: 'Product 1'
}
]);
}
Upload con Preview
<input type="file" (change)="handleFile($event)">
@if (preview()) {
<img [cdnSrc]="preview()!" />
}
Implementación Interna
cdnSrc Transform
transform: value => {
if (typeof value === 'string') return getCdnPublicUrl(value);
if (value instanceof File) {
this.readFile(value); // FileReader
return null;
}
return getCdnPublicUrlAttachment(value);
}
cdnSrcSet Transform
transform: value => {
if (typeof value === 'string') return getCdnPublicUrl(value);
return getCdnPublicUrlAttachment(value);
}
Directivas Relacionadas
- cfSrc / cfSrcSet: Usa endpoint
cloudfront.neten lugar decdn-public.tiendana.com
Diferencia con cfSrc
| Directiva | Endpoint | Uso |
|---|---|---|
cdnSrc / cdnSrcSet | cdn-public.tiendana.com | Endpoint privado de Tiendana |
cfSrc / cfSrcSet | cloudfront.net | CloudFront directo |
Ambas funcionan igual, la diferencia es el endpoint de destino:
// cdnSrc → cdn-public.tiendana.com
<img [cdnSrc]="'assets/logo.svg'" />
<!-- → https://cdn-public.tiendana.com/assets/logo.svg -->
// cfSrc → cloudfront.net
<img [cfSrc]="'assets/logo.svg'" />
<!-- → https://d1234abcd.cloudfront.net/assets/logo.svg -->
Performance
- Cache de transformaciones CDN
- Lazy loading compatible
- FileReader asíncrono para File objects
Accesibilidad
<img
[cdnSrc]="product.image"
[alt]="product.name"
loading="lazy"
width="800"
height="600"
/>