Blog
Description
The blogs/[...slug].vue component renders the detailed view of a single blog article on the Toolstation platform.
It provides SEO enhancements, breadcrumb navigation, share capabilities, tag filtering, and related blog suggestions.
This component dynamically fetches blog data via the builderStore, displays content using structured components, and provides a rich user experience with skeleton loaders and accessibility enhancements.
Purpose
The primary purpose of this page is to present detailed blog content with an engaging interface that supports SEO, social sharing, and navigation through related topics.
Key Functional Goals
- Display Blog Content
- Dynamically fetch and render a single blog post using the
slugfrom the URL. - Display title, publish date, read time, image, and rich text content.
- Dynamically fetch and render a single blog post using the
- SEO and Metadata
- Update
<title>and<meta description>dynamically. - Register structured JSON-LD schema for search engine indexing.
- Update
- Breadcrumb Navigation
- Dynamic breadcrumbs reflecting current blog hierarchy.
- Skeleton Loaders
- While content is loading, show skeleton placeholders for:
- Breadcrumb
- Banner
- Article content
- While content is loading, show skeleton placeholders for:
- Sharing Functionality
- Implements
navigator.share()for Web Share API support. - Populates share data with blog title, description, and URL.
- Implements
- Related Blogs
- Fetch and render other blog posts in a horizontal carousel format.
- Display related blog cards with title, excerpt, and image.
- Tag-Based Navigation
- Display tags as clickable pills.
- Clicking a tag redirects to filtered blog list.
- Support Section
- Show symbol block for customer support at the bottom.
Flow Summary (Step-by-Step)
On page load:
- Reads the blog slug from
route.fullPath. - Calls
builderStore.getBlogItem()to fetch the blog. - Sets
blogDataandbreadcrumb. - Calls
builderStore.getBlogList()to fetch related articles.
While fetching:
- Show animated skeletons for:
- Breadcrumb trail
- Banner with heading and image
- Content paragraphs
After fetch:
- Renders blog content with:
TsBannerOverlayTsContentStaticfor rich content- Tag navigation via
TsTabsCategorySelection - Carousel of related blogs using
TsCarouselV2

🛠️ How to Add Blog Detail from Builder.io
Follow these steps to add a new blog entry using Builder.io:
1. Open Builder.io
- Go to the Builder.io dashboard.
- Navigate to the Page model.
2. Select the Blog Model
- Inside the Page model, choose the
Blogmodel from the options.
3. Create a New Entry
- Click on New Entry.
- Select Blog from the dropdown menu.
4. Enter Basic Information
- Add a Name for your blog page.
(e.g., "LED lighting blog") - Click on Create Page.
5. Add Detailed Information
Fill in all the required fields:
- Title
- Description
- SEO Keywords
- Tags
- Categories
- Experts
- Publish Date
- Blog Image
- Choose Author
6. Publish
- After entering all necessary details, click Publish to make the blog page live.

When user:
- Clicks share → triggers
navigator.share()with blog metadata. - Clicks a tag → navigates to tag-filtered blog list.
- Scrolls to bottom → can access support content via
TsContent.
Computed Properties
headTitle: Returns the blog title for<title>.headMetaDescription: Returns blog SEO description.
Watchers & Lifecycle
onMounted→ Fetch blog and related list.fetchBlog()→ Fetch blog data and populate breadcrumb.fetchBlogsList()→ Load related articles.
Developer Notes
- Uses
defineAsyncComponent()to lazily import components. - Uses
generateContentSchema()to register blog schema (BlogPosting). - Employs
useTranslation()for i18n/localized strings.
🐞 Debugging Guide: Blog Details Page (Nuxt 3 + Pinia + Composition API)
This guide helps troubleshoot issues in the Blog Details Page component using Nuxt 3, Pinia, and Composition API.
✅ Initial Debug Checklist
- Is
blogDatacorrectly populated? - Are async components resolving?
- Are lifecycle hooks (
await fetchBlog(),await fetchBlogsList()) triggering as expected? - Is the breadcrumb rendering the correct title?
- Are skeleton loaders displaying only when data is unavailable?
🔍 Blog Fetch Logic
Confirm getBlogItem is fetching data
In fetchBlog():
console.log("Fetched blog item:", builderStore.blogItem);
console.log("Route fullPath:", route.fullPath);