Saltar al contenido principal

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).

No exportada en la API pública

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.

Tipo Attachment

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​

InputTipoDescripción
cdnSrcstring | File | Attachment | nullURL, 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​

InputTipoDescripción
cdnSrcSetstring | Attachment | nullFuente para srcset
defaultCdnSrcSetstringFallback 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​

@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.net en lugar de cdn-public.tiendana.com

Diferencia con cfSrc​

DirectivaEndpointUso
cdnSrc / cdnSrcSetcdn-public.tiendana.comEndpoint privado de Tiendana
cfSrc / cfSrcSetcloudfront.netCloudFront 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"
/>