usability.cat
Issue Wiki

Unfinished Appearance

Placeholder text, broken images, and half-built sections tell your visitors you don't care. Here's how to ship something that looks done.

What is this?

Imagine walking into a restaurant and being seated at a nice table. The menu looks great. Then your food arrives on a paper plate with a plastic fork, and one wall is unpainted drywall. Suddenly you don't trust the food, the chef, or the five-star reviews. That's what your visitors feel when they land on your site and see "Lorem ipsum dolor sit amet," a broken image icon, an empty "Coming soon!" section, or a button that says "Click here" and goes nowhere. Unfinished signals unsafe. The cat doesn't dine at paper-plate establishments.

Why it matters

  • For your visitors: Placeholder content creates immediate distrust. Your visitors wonder: "If they didn't finish the website, did they finish the product?" It doesn't matter if your app is rock-solid behind the scenes — visible incompleteness makes people question everything. First impressions are formed in 50 milliseconds, and a broken image takes zero milliseconds to notice.

  • For your business: Unfinished appearance is the fastest way to kill credibility, especially for new products trying to build trust. Visitors mentally categorize your site as either "legitimate business" or "someone's side project." Lorem ipsum, missing images, and dead links push you firmly into the second category. Even a minimal page that's polished beats a feature-rich page that's half-done.

  • The standard: Every visible element on your site should be intentional and complete. If a section isn't ready, remove it entirely rather than shipping it half-built. Use real content (not placeholder text), real images (not broken links), and functional interactions (no dead buttons). A smaller, finished site always beats a larger, unfinished one.

Intentionally minimal but complete
<section class="py-24 px-6">
  <h2 class="text-3xl font-bold">What our users say</h2>
  <blockquote class="mt-8 border-l-2 border-amber-500 pl-6">
    <p class="text-lg text-neutral-300">
      "Saved me 10 hours of manual testing."
    </p>
    <cite class="mt-2 block text-sm text-neutral-500">
      — Alex Chen, founder of ShipFast
    </cite>
  </blockquote>
</section>
Obviously placeholder
<section class="py-8">
  <h2>Testimonials</h2>
  <div class="testimonial">
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing.</p>
    <span>— John Doe, Company Name</span>
  </div>
  <div class="testimonial">
    <img src="/images/user2.jpg" alt="" /> <!-- broken image -->
    <p>Coming soon!</p>
  </div>
  <button disabled>Load more</button>
</section>

How to fix it

React / Next.js

Build a checklist component that helps you audit before shipping. More importantly, adopt the pattern of rendering nothing instead of rendering something broken:

// Don't render incomplete sections — conditionally show them
export function TestimonialsSection({
  testimonials,
}: {
  testimonials: Array<{ quote: string; author: string; role: string }>;
}) {
  // No testimonials yet? Don't render an empty section.
  if (testimonials.length === 0) return null;

  return (
    <section className="py-20 px-6">
      <h2 className="text-center text-2xl font-bold text-white">What people are saying</h2>
      <div className="mx-auto mt-12 grid max-w-4xl gap-8 md:grid-cols-2">
        {testimonials.map((t) => (
          <blockquote key={t.author} className="border border-neutral-800 bg-neutral-900 p-6">
            <p className="text-neutral-300">&ldquo;{t.quote}&rdquo;</p>
            <footer className="mt-4 text-sm text-neutral-500">
              {t.author}, {t.role}
            </footer>
          </blockquote>
        ))}
      </div>
    </section>
  );
}

// Handle images with proper fallbacks
export function Avatar({ src, name }: { src?: string; name: string }) {
  if (!src) {
    // Fallback: initials on a colored background — never a broken image
    return (
      <div className="flex h-10 w-10 items-center justify-center rounded-full bg-amber-500/20 text-sm font-bold text-amber-400">
        {name.charAt(0).toUpperCase()}
      </div>
    );
  }
  return (
    <img
      src={src}
      alt={name}
      className="h-10 w-10 rounded-full object-cover"
      onError={(e) => {
        e.currentTarget.style.display = "none";
      }}
    />
  );
}

Plain HTML / CSS

/* Hide sections that aren't ready instead of showing placeholders */
.section--draft {
  display: none;
}

/* Image fallbacks with CSS */
img {
  background: #262626;
  min-height: 200px;
  object-fit: cover;
}

/* Broken image styling — hide the alt icon */
img::after {
  content: attr(alt);
  display: flex;
  align-items: center;
  justify-content: center;
  position: absolute;
  inset: 0;
  background: #262626;
  color: #a3a3a3;
  font-size: 0.875rem;
}

/* Style empty states so they feel intentional */
.empty-state {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3rem;
  border: 2px dashed #404040;
  border-radius: 0.75rem;
  color: #737373;
  font-style: italic;
}
High impactvisualDesign~2 paws

Placeholder content and broken assets are instant credibility killers. The cat gives zero mercy for Lorem ipsum on a production site. If it's not ready, hide it. If it's visible, finish it.

How the cat scores this

The scanner looks for common unfinished indicators: Lorem ipsum and other placeholder text patterns, broken images (elements that failed to load), empty sections with no meaningful content, links that point to # or javascript:void(0), buttons with generic text like "Click here" or "Submit," and disabled interactive elements without explanation. Each instance is flagged, and multiple instances severely impact your score.

Further reading

On this page