Latest insights
Explore Our Latest Blogs
Discover technical intelligence, market commentary, and expert
perspectives shaping the semiconductor industry.
View all blogs
→
Search blogs
×
Sort blogs
Newest first
Oldest first
Title: A to Z
Title: Z to A
All
AI & Data Centers
Memory & Packaging
Market Analysis
Devices & Teardowns
Connectivity
Sustainability
Power & Automotive
Loading blog archive...
Clear filters
No matching insights found
Try another search term or clear your filters.
View all blogs
Load more insights
↓
`;
const loadingText =
blog.metadataState === "loading"
? `
Loading details...
`
: "";
return `
${imageMarkup}
${escapeHTML(blog.category)}
${formattedDate}
${
blog.excerpt
? `
${escapeHTML(blog.excerpt)}
`
: loadingText
}
Read insight
→
`;
}
function renderBlogs(allowHydration = true) {
const filteredBlogs = getFilteredBlogs();
const visibleBlogs = filteredBlogs.slice(
0,
visibleCount
);
const total = filteredBlogs.length;
grid.innerHTML = visibleBlogs
.map((blog, index) => createCard(blog, index))
.join("");
if (total === 0) {
count.textContent = "No insights found";
} else if (total === 1) {
count.textContent = "Showing 1 insight";
} else {
count.textContent =
`Showing ${Math.min(visibleCount, total)} of ${total} insights`;
}
emptyState.hidden = total !== 0;
grid.hidden = total === 0;
loadMore.hidden =
total === 0 ||
visibleCount >= total;
const hasFilters =
activeCategory !== "All" ||
searchInput.value.trim() !== "";
resetFilters.hidden = !hasFilters;
clearSearch.hidden =
searchInput.value.length === 0;
/*
* Retrieve full metadata only for sitemap-only
* articles currently visible to the visitor.
*/
if (allowHydration) {
hydrateVisibleBlogs(visibleBlogs);
}
}
function resetAll() {
activeCategory = "All";
visibleCount = 8;
searchInput.value = "";
sortSelect.value = "newest";
filterButtons.forEach(button => {
button.classList.toggle(
"is-active",
button.dataset.category === "All"
);
});
renderBlogs();
}
async function loadCompleteBlogIndex() {
grid.innerHTML = `
Finding every TechInsights blog...
`;
searchInput.disabled = true;
sortSelect.disabled = true;
loadMore.hidden = true;
filterButtons.forEach(button => {
button.disabled = true;
});
try {
/*
* Load every /blog/ URL from all sitemap files.
*/
const sitemapBlogs = await loadSitemapBlogs();
sitemapBlogs.forEach(blog => {
blogIndex.set(
normalizeURL(blog.url),
blog
);
});
count.textContent =
`${sitemapBlogs.length} blogs found. Loading latest details...`;
/*
* Merge richer titles, descriptions, dates,
* and images from the regular blog listing.
*/
const archiveBlogs =
await loadLatestArchiveMetadata();
archiveBlogs.forEach(blog => {
const key = normalizeURL(blog.url);
const existingBlog = blogIndex.get(key);
blogIndex.set(key, {
...existingBlog,
...blog,
metadataState: "loaded"
});
});
blogs = Array.from(blogIndex.values());
renderBlogs();
} catch (error) {
console.error(
"Complete blog index could not be loaded:",
error
);
count.textContent =
"The complete blog archive could not be loaded.";
grid.innerHTML = `
`;
} finally {
searchInput.disabled = false;
sortSelect.disabled = false;
filterButtons.forEach(button => {
button.disabled = false;
});
}
}
filterButtons.forEach(button => {
button.addEventListener("click", () => {
activeCategory = button.dataset.category;
visibleCount = 8;
filterButtons.forEach(item => {
item.classList.toggle(
"is-active",
item === button
);
});
renderBlogs();
});
});
searchInput.addEventListener("input", () => {
visibleCount = 8;
renderBlogs();
});
clearSearch.addEventListener("click", () => {
searchInput.value = "";
visibleCount = 8;
searchInput.focus();
renderBlogs();
});
sortSelect.addEventListener("change", () => {
visibleCount = 8;
renderBlogs();
});
loadMore.addEventListener("click", () => {
visibleCount += 8;
renderBlogs();
});
resetFilters.addEventListener(
"click",
resetAll
);
emptyReset.addEventListener(
"click",
resetAll
);
loadCompleteBlogIndex();
})();