Blog SaaS 7 min read

Job Board Company Logo and Avatar Fallbacks

Keep company logos and user profile avatars stable on job boards with fallback.pics. Handle missing logos, unverified company accounts, and 404 avatar URLs.

company logo placeholderjob board image fallbackavatar placeholderemployer logo fallbackSaaS image fallback
Job Board Company Logo and Avatar Fallbacks

Job boards display two distinct image types: company logos on job listings and user profile avatars for candidates and recruiters. Both fail regularly. Company accounts go inactive and their CDN assets expire; users sign up without uploading a photo; logos from external HR systems arrive via feeds that break silently.

Initials-based avatar placeholders and branded logo fallbacks are the two tools that solve these problems. fallback.pics provides both via URL: the /avatar/ route for initials avatars and the standard colored tile for company logo placeholders.

Company logos

Logo fallbacks for employer accounts

Company logos on job listings fail for several reasons: a startup changes its logo and forgets to update the job board; an enterprise company rotates its CDN and breaks all externally-linked logo URLs; a free-tier company account lapses and their hosted assets go offline.

A fallback that uses the company name's first letters on a brand-colored background reads as an intentional design choice (think Google's G, Amazon's A) rather than a missing image. This is the standard UI pattern for all company identities that lack a photo.

Logo avatar route

Generate company initials avatars from the URL

The /avatar/ route accepts a text parameter for initials. Use the first letter of the company name or the first two letters for multi-word names. The output is a circular or square avatar tile with the initials centered.

Vary the background color by company ID or name hash to give each company a distinct color without manual setup. A simple modulo operation on the name length or character codes selects from a set of brand-safe colors.

Implementation tsx
const COMPANY_COLORS = [
  '7C3AED', '2563EB', '0D9488', '16A34A', 'CA8A04',
  'DC2626', 'C026D3', '0369A1', '15803D', 'D97706',
];

function companyInitials(name: string): string {
  const words = name.trim().split(/s+/);
  return words.length > 1
    ? (words[0][0] + words[1][0]).toUpperCase()
    : name.slice(0, 2).toUpperCase();
}

function companyLogoFallback(name: string, size = 64): string {
  const initials = companyInitials(name);
  const colorIndex = name.charCodeAt(0) % COMPANY_COLORS.length;
  const bg = COMPANY_COLORS[colorIndex];
  return `https://fallback.pics/api/v1/avatar/${size}?text=${encodeURIComponent(initials)}&bg=${bg}`;
}

// companyLogoFallback('Acme Corp', 64)
// companyLogoFallback('Stripe', 40)

Job listing card

Logo on job listing cards and search results

Job listing search result cards show the company logo at 40–64px square alongside the job title, company name, and location. At this size, the initials fit perfectly and distinguish each company visually.

Apply the fallback both for missing logos and for failed image loads. Check the company logo field server-side and default to the fallback URL if it is null or empty. The onerror handler covers URL-exists-but-returns-404 failures at render time.

Implementation tsx
function JobListingCard({ job }: { job: JobListing }) {
  const fallback = companyLogoFallback(job.company.name, 48);
  return (
    <article>
      <img
        src={job.company.logoUrl ?? fallback}
        width={48}
        height={48}
        alt={`${job.company.name} logo`}
        onError={(e) => { e.currentTarget.src = fallback; }}
      />
      <div>
        <h3>{job.title}</h3>
        <p>{job.company.name} · {job.location}</p>
      </div>
    </article>
  );
}

User avatars

Candidate and recruiter profile avatar fallbacks

User profile avatars for candidates and recruiters fail when users sign up without uploading a photo, when OAuth-linked profile photos expire (Google, LinkedIn profile URLs are not stable long-term), or when accounts are anonymised for privacy.

The /avatar/ route with the user's initials is the right fallback for authenticated user avatars. Vary the color based on the user's ID (not name — names can change) for a consistent per-user color.

Implementation tsx
function userAvatarFallback(userId: string, displayName: string, size = 40): string {
  const initials = displayName
    .split(' ')
    .filter(Boolean)
    .map(w => w[0].toUpperCase())
    .slice(0, 2)
    .join('');

  // Stable color based on userId hash
  const hash = userId.split('').reduce((acc, c) => acc + c.charCodeAt(0), 0);
  const bg = COMPANY_COLORS[hash % COMPANY_COLORS.length];

  return `https://fallback.pics/api/v1/avatar/${size}?text=${encodeURIComponent(initials || '?')}&bg=${bg}`;
}

Recruiter tools

Recruiter dashboard and ATS integration fallbacks

Applicant tracking systems (ATS) pull candidate photos from LinkedIn via integrations that periodically break. Resume parsing systems may attach a photo URL that was embedded in a PDF and is no longer accessible. Recruiter-facing tools see avatar failures at a higher rate than public-facing job boards.

Apply the user avatar fallback at the recruiter dashboard component level. The same component serves both the job board and the recruiter app, so one change propagates to both surfaces.

Implementation tsx
// UserAvatar component – shared between candidate card and recruiter dashboard
export function UserAvatar({
  user,
  size = 40,
}: {
  user: { id: string; displayName: string; avatarUrl?: string };
  size?: number;
}) {
  const fallback = userAvatarFallback(user.id, user.displayName, size);
  return (
    <img
      src={user.avatarUrl ?? fallback}
      width={size}
      height={size}
      alt={user.displayName}
      onError={(e) => { e.currentTarget.src = fallback; }}
      style={{ borderRadius: '50%' }}
    />
  );
}

Unverified accounts

Placeholder logos for unverified company accounts

Job boards let companies post jobs before completing profile verification. An unverified account may not have uploaded a logo yet. Use a distinct placeholder color or label for unverified accounts to signal their status in moderation and public-facing views.

Swap to the standard initials fallback once the account is verified and a logo is still missing.

Implementation tsx
const logoSrc =
  company.logoUrl
    ? company.logoUrl
    : company.verified
      ? companyLogoFallback(company.name, 48)
      : `https://fallback.pics/api/v1/avatar/48?text=?&bg=94A3B8`;

Further reading

Avatar and logo fallbacks in SaaS platforms

The same initials-based avatar pattern used on job boards works across all SaaS products that show user and organization identities. Build it into a shared design system component once and reuse it everywhere.

Implementation text
# https://fallback.pics/docs/
# https://fallback.pics/placeholder-image-api/
# https://fallback.pics/blog/avatar-placeholder-generator-initials-colors-accessibility/
# https://fallback.pics/blog/branded-fallback-images-saas-dashboards-internal-tools/

Key takeaways

What to standardize before shipping

  • Generate company initials from the name and assign a consistent color via a hash of the name.
  • Use user ID, not display name, to assign a stable avatar color across name changes.
  • Apply fallbacks server-side for missing logo fields and client-side onerror for URL failures.
  • Unverified company accounts should show a distinct placeholder, not the standard initials tile.
  • LinkedIn and OAuth profile photo URLs are not stable long-term — always have a fallback ready.

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