Blog SaaS 6 min read

Support Ticket Attachment Preview Fallbacks

Handle broken and unpreviewable attachments in support ticket systems with typed attachment preview placeholder images that communicate file type without a broken icon.

attachment preview placeholdersupport ticket imagesfile attachment fallbackimage fallbackSaaS support tools
Support Ticket Attachment Preview Fallbacks

Support ticket systems display attachment thumbnails inline in the conversation thread. When an attachment is a non-image file or a broken image URL, the default broken image icon is unhelpful—it gives the support agent no information about what the customer attached. Attachment preview placeholder images replace the broken icon with a type-aware visual that communicates file format at a glance.

The fallback.pics API generates file-type labeled placeholder images from a URL. Map each MIME type or file extension to a colored placeholder and your support UI handles every attachment type consistently.

The broken attachment problem

Why support ticket attachment previews break

Support ticket systems receive files from customers over email, web forms, and mobile apps. The file types are unpredictable: PDFs, screenshots, log files, spreadsheets, recordings, archives. Many support tools try to render all attachments as img elements and fall back to a broken icon for anything that is not a browser-renderable image format.

A second failure mode is URL expiration. Most support platforms store attachments in object storage with signed URLs that expire after a period. If an agent revisits an old ticket, attachment URLs from 90+ days ago may be expired, producing 404 responses for every thumbnail.

Both failure modes produce the same broken icon. A type-aware placeholder replaces the broken icon with useful information.

Type mapping

File type to placeholder color and label mapping

A small mapping from MIME type or file extension to placeholder URL provides the foundation for type-aware attachment previews. Use distinct colors that agents can learn to recognize at a glance: red for documents, green for spreadsheets, blue for PDFs, orange for videos, yellow for archives.

Implementation tsx
const ATTACHMENT_PLACEHOLDERS: Record<string, string> = {
  'application/pdf':
    'https://fallback.pics/api/v1/120x120/EF4444/FFFFFF?text=PDF',
  'application/msword':
    'https://fallback.pics/api/v1/120x120/3B82F6/FFFFFF?text=DOC',
  'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
    'https://fallback.pics/api/v1/120x120/3B82F6/FFFFFF?text=DOCX',
  'application/vnd.ms-excel':
    'https://fallback.pics/api/v1/120x120/10B981/FFFFFF?text=XLS',
  'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
    'https://fallback.pics/api/v1/120x120/10B981/FFFFFF?text=XLSX',
  'text/csv':
    'https://fallback.pics/api/v1/120x120/10B981/FFFFFF?text=CSV',
  'video/mp4':
    'https://fallback.pics/api/v1/120x120/F97316/FFFFFF?text=MP4',
  'application/zip':
    'https://fallback.pics/api/v1/120x120/8B5CF6/FFFFFF?text=ZIP',
  'text/plain':
    'https://fallback.pics/api/v1/120x120/71717A/FFFFFF?text=TXT',
  default:
    'https://fallback.pics/api/v1/120x120/71717A/FFFFFF?text=FILE',
};

function attachmentPlaceholder(mimeType: string): string {
  return ATTACHMENT_PLACEHOLDERS[mimeType] ?? ATTACHMENT_PLACEHOLDERS.default;
}

Render pattern

AttachmentPreview component for support UIs

The component logic is: if the attachment is an image MIME type, render with src and an onerror fallback. If it is any other type, render the type placeholder directly as the src. Never try to render a PDF or DOCX as an img src.

Implementation tsx
interface AttachmentPreviewProps {
  url: string;
  mimeType: string;
  filename: string;
  size?: number;
}

export function AttachmentPreview({
  url,
  mimeType,
  filename,
  size = 120,
}: AttachmentPreviewProps) {
  const isImage = mimeType.startsWith('image/');
  const placeholder = attachmentPlaceholder(mimeType);

  return (
    <a href={url} target="_blank" rel="noopener noreferrer" title={filename}>
      <img
        src={isImage ? url : placeholder}
        width={size}
        height={size}
        alt={filename}
        onError={
          isImage
            ? (e) => {
                e.currentTarget.onerror = null;
                e.currentTarget.src = placeholder;
              }
            : undefined
        }
      />
    </a>
  );
}

Expired URLs

Handle expired signed storage URLs in old tickets

When an agent opens an old ticket, the attachment URL may have expired. Rather than showing broken icons throughout the conversation, detect the 404 at component mount and replace with a type placeholder proactively.

A HEAD request at mount time catches expired URLs before the img element tries to load them, preventing the brief broken-icon flash that onerror-only approaches produce.

Implementation tsx
function useAttachmentSrc(url: string, mimeType: string) {
  const [src, setSrc] = useState(
    mimeType.startsWith('image/') ? url : attachmentPlaceholder(mimeType)
  );

  useEffect(() => {
    if (!mimeType.startsWith('image/')) return;
    fetch(url, { method: 'HEAD' }).then((res) => {
      if (!res.ok) setSrc(attachmentPlaceholder(mimeType));
    });
  }, [url, mimeType]);

  return src;
}

Zendesk / Intercom

Custom attachment rendering in Zendesk and Intercom apps

Both Zendesk Apps Framework and Intercom App Kit allow custom rendering of ticket attachment areas. If you are building a support sidebar app, you can override the default attachment preview with your own component and apply the type-aware placeholder logic.

For Zendesk, use the ticket.comment.attachments API to get MIME types and URLs. For Intercom, the conversation.parts[].attachments array provides the same data. Both give you enough information to apply the file type mapping.

Key takeaways

What to standardize before shipping

  • Never render non-image MIME types as img src—use a file type placeholder directly instead of attempting to render and catching the error.
  • Map MIME types to distinct colored placeholder images so support agents recognize file formats without reading the filename.
  • Detect expired signed storage URLs with a HEAD request at component mount to avoid brief broken-icon flashes in old tickets.
  • Both Zendesk and Intercom provide MIME type data in their attachment APIs, enabling type-aware placeholder rendering in sidebar apps.
  • Keep the onerror handler active for image MIME types to handle CDN failures and encoding errors.

Production fallback layer

Use fallback.pics anywhere an image URL is accepted.

Start with one deterministic URL and standardize fallback behavior across your design system.

Read the docs