跳到正文
DEV Community· Nikola Sava·· 3 小時前AI 評分57

一次真實 SaaS 審核列出 7 個同時影響用戶體驗與 SEO 的問題

7 UX Problems That Were Also Hurting SEO (From a Real SaaS Audit)

AI 導讀

作者根據一次小型 SaaS 審核,整理出 7 個同時影響用戶體驗與 SEO 的問題,並為每項列出修正方法及自查方式。問題包括定價頁需登入、首頁缺少清晰產品説明、導覽及圖片替代文字不足、手機效能慢,以及只追蹤瀏覽量;估算約 2.8% 首頁訪客開始免費試用。

正文

A while ago I audited a small SaaS that turns photos into short videos. The brief was simple: people visit, few of them sign up, figure out why.

When we rebuilt the funnel from their analytics, roughly 2.8% of homepage visitors got as far as starting a free trial. That's an estimate, not a precise number, but it was clearly below where it should be.

I kept two columns in my notes: "hurts users" and "hurts search visibility". By the end, most items sat in both. Below are the seven that overlapped, with the fix and a quick way to check your own site for each one.

1. The pricing page was behind a login

What users saw. A "Pricing" link that opened a sign-up form. To find out what the product costs, you had to create an account first. Most people who just want a price won't trade their email for it, so they left.

This was also the biggest single drop in the estimated funnel:

Step Visitors Lost since the row above
Homepage visit 1,000
Clicked a CTA 320 68%
Viewed pricing 180 44%
Started sign-up 120 33%
Started free trial 28 77%

Website wireframe with highlighted problems linked to both users and search engines

What search engines saw. A redirect to the login page. Crawlers don't create accounts, so /pricing was never indexed. Searches like "[product] pricing" or "[product] cost" ended up on review sites and competitor comparison pages. AI assistants answering "how much does [product] cost" pulled from the same third-party pages, some with outdated prices.

Fix. Make the pricing page public and put the prices in the HTML. Keep checkout, billing and the app itself behind auth.

If you protect routes in middleware, look at the matcher first. A broad rule often catches marketing pages by accident.

Before:

export const config = { matcher: ['/((?!$).*)'] };

After:

export const config = { matcher: ['/app/:path*', '/account/:path*', '/billing/:path*'] };

Check.

curl -sI https://yoursite.com/pricing | head -n 3

You want a 200. A 301 or 302 to /login means crawlers never see the page. Then run the URL through URL Inspection in Google Search Console to confirm it can be indexed.

2. The homepage had no H1 and no clear offer

What users saw. A short line of small text and a "See examples" button. Nothing said what the product does, who it's for, or why it beats doing the same thing by hand.

What search engines saw. No H1 at all, and almost no text above the fold. The page ranked for the brand name and very little else, because nothing on it stated the topic in the words people search with.

Fix. One H1 that says what the product does in your customers' words, and one line under it with who it's for and the main benefit.

<h1>Turn your photos into a short video in minutes</h1>
<p>For creators and small teams. Upload, pick a style, export. No editing skills needed.</p>

Check. Paste this into the browser console:

[...document.querySelectorAll('h1')].map(h => h.textContent.trim())

You want one H1 that a stranger would understand. Then do the five-second test: show the first screen to someone who has never seen the site, hide it after five seconds, and ask what the product does.

3. After the hero, the page jumped straight to reviews

What users saw. No "how it works", no features. Just testimonials praising a product the visitor still didn't understand.

What search engines saw. Very little text describing the product, so little to match against queries like "photo to video maker" or "make a video from pictures online". A homepage that thin competes on its brand name only.

Fix. Add a three-step "How it works" and a features block with real headings. Not a wall of SEO copy, just the answers a buyer looks for.

<section>
  <h2>How it works</h2>
  <ol>
    <li><h3>Upload your photos</h3><p>JPG, PNG or HEIC, straight from your phone.</p></li>
    <li><h3>Pick a style</h3><p>Change colors, timing and music.</p></li>
    <li><h3>Export</h3><p>Download in 1080p and share anywhere.</p></li>
  </ol>
</section>

Check. Open the homepage in reader mode or with images turned off. If you can't tell how the product works from the text alone, a crawler can't either.

4. Navigation hid the pages people look for

What users saw. A header with a couple of links. No Pricing, no FAQ, no About. Anyone looking for basic answers had nowhere to click.

What search engines saw. Internal links are how crawlers find pages and judge which ones matter. Pages linked only from the footer, or not linked at all, get crawled less often and look less important.

Fix. Put the pages buyers look for in the header, as plain links.

<nav>
  <a href="/features">Features</a>
  <a href="/pricing">Pricing</a>
  <a href="/examples">Examples</a>
  <a href="/faq">FAQ</a>
  <a href="/about">About</a>
</nav>

Avoid links built from click handlers, like <span onclick="router.push('/pricing')">. Crawlers follow href, not JavaScript events.

Check. In Google Search Console, open Links → Internal links. Your pricing and feature pages should be near the top of the list, not at the bottom.

5. Images had no alt text

What users saw. Screen reader users heard file names or nothing. Everyone else saw the same blank boxes when an image failed to load on a slow connection.

What search engines saw. For a video tool, the example gallery was the most convincing content on the site. Without alt text, none of it existed as text: no image search traffic, and no description of what the product produces.

Fix. Describe what the image shows, briefly. Decorative images get an empty alt so screen readers skip them. Set width and height while you're there, so the layout doesn't jump when images load.

<img src="example-beach.webp" alt="30-second video made from 12 beach photos with fade transitions" width="1200" height="675">
<img src="divider.svg" alt="">

Check. In the console:

[...document.images].filter(i => !i.hasAttribute('alt')).map(i => i.src)

An empty array is what you want.

6. Mobile was slow: LCP 3.2 s, INP 280 ms

Metric (mobile) Measured Good
Performance score 60 90+
LCP 3.2 s under 2.5 s
INP 280 ms under 200 ms
CLS 0.08 under 0.1 (passed)

What users saw. On a phone, the hero took over three seconds to appear, and buttons felt sluggish after a tap.

What search engines saw. LCP and INP are part of Core Web Vitals, which search engines use as a page experience signal. It's not the strongest ranking factor, but with mobile-first indexing the mobile version is the one being evaluated.

Fix. Two changes usually move these numbers the most.

For LCP, load the hero image early and never lazy-load anything in the first screen:

<link rel="preload" as="image" href="/img/hero.webp" fetchpriority="high">
<img src="/img/hero.webp" alt="Video editor showing a finished clip" width="1200" height="675" fetchpriority="high">

For INP, keep third-party scripts (chat widgets, heatmaps, extra analytics) out of the critical path, and give the browser a chance to paint before heavy work runs after a click:

<script src="https://chat-widget.example/loader.js" defer></script>
button.addEventListener('click', async () => {
  showSpinner();
  await new Promise(resolve => setTimeout(resolve, 0));
  runHeavyWork();
});

Check. Run PageSpeed Insights on mobile. If your site has enough traffic, look at the field data section, not only the lab score. The Core Web Vitals report in Search Console groups slow URLs for you.

7. Nothing was tracked beyond pageviews

What users saw. Nothing. But this is why the team couldn't say where people dropped off, and why the funnel above is an estimate.

What search engines saw. Nothing either. The SEO cost is indirect: Search Console tells you which pages get search traffic, but without conversion events you can't tell which of those pages bring sign-ups. So you end up chasing clicks instead of customers.

Fix. A handful of GA4 events covers most of it:

document.querySelectorAll('[data-cta]').forEach(el => {
  el.addEventListener('click', () => {
    gtag('event', 'cta_click', { location: el.dataset.cta });
  });
});

if (location.pathname === '/pricing') {
  gtag('event', 'view_pricing');
}

Mark sign_up as a key event, then compare organic landing pages by sign-ups, not by sessions.

Check. Open DebugView in GA4, click through your own site, and watch the events arrive.

What didn't overlap

Not everything on the list was an SEO problem, and I don't want to pretend otherwise. These hurt users only, and they still mattered:

  • Text contrast of 1.8:1 on the homepage, against a WCAG AA minimum of 4.5:1. Unreadable in sunlight on a phone.
  • Buttons around 32 px tall on mobile. Google and Apple both recommend at least 44–48 px touch targets.
  • A sign-up form with 12 fields, including company, job title and phone, for a free trial of a video tool. Email and password were enough.
  • Pricing cards that all looked the same. No highlighted plan, no comparison table, so people couldn't decide.

None of these will move rankings. All of them move sign-ups, which is the reason anyone cares about rankings in the first place.

A 15-minute check for your own site

  1. curl -sI your pricing page. Is it a 200 without logging in?
  2. Count the H1s on your homepage. Is there one, and does it say what you do?
  3. Read the homepage in reader mode. Can you explain the product from the text alone?
  4. Is Pricing in the header as a real <a href> link?
  5. Run the alt text snippet. Any images left without alt?
  6. Run PageSpeed Insights on mobile. Are LCP under 2.5 s and INP under 200 ms?
  7. Click your main CTA with GA4 DebugView open. Does an event show up?

If you fail two or more, start with the pricing page. It's usually the cheapest fix with the biggest effect on both sides.

The common thread: most of these were never "SEO tasks" or "UX tasks" on anyone's list. They fell between the designer, the developer and whoever handled marketing. That gap is why I look at both together in a UX SEO audit instead of splitting them into two reports.

What's the worst one you've found on a site you worked on? I'm curious whether gated pricing is as common as it seems.

來源:DEV Community · dev.to