Building an ecommerce app using Angular comes with its demands, and the focus is majorly on seamless functionalities. You want your web app to function smoothly, with dynamic interfaces and a beautiful UI of course. While there is no harm in these objectives, there is also no harm in considering the SEO perspective during development. Good HTML helps Google rank your web app and makes it easier for users to find it in the first place.
So imagine the horror of discovering that while the website was visually and functionally amazing, it wasn't doing so well in terms of SEO ranking — because from Google's perspective, there was no structure. No clear signals about what the page was about or what content mattered most.
Let's dive in.
When Everything is a div, span or p Tag
Because this wasn't a company's website or a blog, it seemed fine to just have everything wrapped in divs and represented with spans and paragraphs. Page titles, section headings, product names, product descriptions — all in <p> or <span> tags, with CSS doing the heavy lifting to give them unique font sizes, weights, and colors.
<p class="text-lg font-semibold">
Black Andi Dress
</p>
From a UI standpoint, it looked good. The structure appeared fine. But from Google's perspective, it was not.
Search engines do not read user interfaces the way users do. Instead, they rely on semantic structure to understand what a page is about, which content is important, and what should be prioritized. So, when you have just divs and paragraphs with cool styling, Google sees it as plain text everywhere on the page — no primary subject to anchor to, no product name to elevate, no page title to latch onto.
What Google is actually looking for when it crawls your page:
| Tag | What it tells Google |
|---|---|
<h1> |
Main topic of the page |
<h2>, <h3> |
Sections and sub-sections |
<p> |
Supporting content or descriptions |
<a> |
Crawlable navigation paths |
Without those signals, Google can't confidently say "this page is about the Black Andi Dress." It just sees "Black Andi Dress" as another piece of text floating somewhere on the page. No context. No hierarchy. No ranking advantage.
This is how leaning entirely on div and p tags with functional logic actively harms the SEO of your ecommerce application.
What Even Is Semantic HTML?
According to w3schools, A semantic element clearly describes its meaning to both the browser and the developer.
- Examples of non-semantic elements are div and span tags which tells nothing about its content.
- Examples of semantic elements are h1, img, table, and article tags which clearly defines its content.
The key distinction is intentionality. Semantic HTML is about choosing tags that reflect what the content is, not just what it looks like.
Why Semantic HTML matters beyond SEO
Semantic HTML isn't just an SEO trick. It delivers real benefits across the board:
Accessibility — Screen readers and assistive technologies rely on semantic structure to help users with disabilities navigate a page. When everything is a <div>, a screen reader has no way of knowing where the navigation is, where the main content begins, or what the heading hierarchy looks like. Semantic tags provide those cues clearly.
Code maintainability — When you return to a codebase six months later (or hand it off to another developer), semantic HTML makes intent obvious. Finding a nav to update is far easier than hunting through a sea of <div class="nav-wrapper-2">.
Better user experience — When content is organized with meaningful tags, browsers can render pages more predictably, and users can navigate more intuitively — especially those using keyboard navigation or browser reader modes.
The Good News: You Don't Need to Touch the UI
The most common fear when fixing semantic HTML is: "If we change the tags, we'll break the design." That fear is largely unfounded, especially when using utility-first CSS like Tailwind.
Your classes stay exactly the same. You're just changing the wrapper:
Before ❌
<p class="text-lg font-semibold">
Black Andi Dress
</p>
After ✅
<h2 class="text-lg font-semibold">
Black Andi Dress
</h2>
No visual regression. No layout shifts. Same Tailwind classes. Massive semantic improvement.
The same logic applies across your product pages — promote product names to <h1> on detail pages, convert section titles to <h2> or <h3> where appropriate, and let heading hierarchy reflect the actual importance of content rather than how big you want the text to look.
Where It Gets Tricky in Angular and React
Frameworks introduce a subtle but important confusion: components that look semantic aren't always semantically correct at the HTML level.
In React, for example, libraries like Semantic UI offer components named <Header> and <Footer>. These look familiar, but they don't always output actual <header> or <footer> HTML elements. The underlying HTML may vary — and what Google reads is the rendered HTML, not the component names.
In Angular, the trap is slightly different. Consider this:
<p [routerLink]="['/stores', storeName, productCode]">
Black Andi Dress
</p>
This navigates correctly when a user clicks it. Angular handles the routing perfectly. But from Google's perspective, this is just a paragraph of text. It is not a linK, hence, Google will not recognize it as such.
| Tag Implementation | Crawlable by Google | SEO Value |
|---|---|---|
<p routerLink> |
NO | NO |
<div (click)> |
NO | NO |
<a routerLink> |
YES | YES |
<a href> |
YES | YES |
The correct fix is to use an actual <a> tag with routerLink:
<a [routerLink]="['/stores', singlestore.storename ]"
class="p-3 font-medium text-sm text-green-400 hover:text-green-600 transition-colors"
title="{{ product?.product_name }}"
>
{{ product?.product_name }}
</a>
Angular renders this as a proper <a href="..."> in the DOM — one that Google can crawl, follow, and use to discover product pages.
Best Practices
A few principles to keep front of mind as you work through this:
-
One
<h1>per page, preferably: The<h1>signals the primary topic of a page to search engines. Multiple<h1>tags dilute that signal. On a product detail page, the product name gets the**<h1>**. On a listing page, the same product name might only warrant an**<h3>**.
Headings define importance, not appearance. This is the most common misunderstanding. If you need a small-looking heading, use the appropriate heading tag and control the size with CSS. Don't reach for a **<p>** tag just because you want smaller text.
A basic, effective heading structure for a product page looks like this:
<h1>Black Andi Dress</h1>
<h2>Product Description</h2>
<h2>Specifications</h2>
<h2>Pricing & Availability</h2>
Even two or three clear headings dramatically improve SEO clarity for the page.
Combine semantic tags for compounding effect. Link equity and heading signals stack:
<h3>
<a [routerLink]="...">Black Andi Dress</a>
</h3>
-
Don't use
<div (click)>or<p routerLink>for navigation: If something should be a link, it should be an**<a>**tag.
Use semantic structure tags to define regions. Wrap your navigation in <nav>, your main content in <main>, your page header in <header>. These tags cost nothing to add and give Google a clearer map of your page.
- Don't use HTML to style — that's CSS's job: Use tags to describe what content is, and let your stylesheet handle how it looks. This separation keeps your markup clean, meaningful, and maintainable.
Conclusion
Semantic HTML is not outdated. It's not a relic of the pre-framework era. And modern frameworks — as powerful as they are — do not replace it.
Even in a fully dynamic Angular SPA, Google still depends on semantic structure to understand your content.
It's a matter of being intentional about the tags you reach for — choosing <h1> because that element is the main heading, choosing <a> because that element is a link. The styling stays the same. The SEO impact does not.
Build beautiful. Build functional. But also build with meaning — because that's what gets you found.
Top comments (0)