mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
feat: add 52 per-tool SEO landing pages and public changelog (#145)
* feat: add 52 per-tool SEO landing pages and public changelog
- Create individual landing pages for all 52 tools at /tools/{slug}
with search-intent title tags, unique FAQs (156 Q&As), per-tool
features, and rich schema markup (BreadcrumbList, WebApplication,
HowTo, FAQPage)
- Replace static sitemap.xml with dynamic generation including all
tool URLs
- Refactor bento grid to import from @snapotter/shared (eliminates
330 lines of duplicated tool data) and link cards to tool pages
- Add @snapotter/shared as workspace dependency to landing site
- Add public changelog page to docs site with curated release notes
from v1.8 through v1.17
- Update docs nav and sidebar with changelog link
* feat: enhance SEO and performance with updated metadata, robots.txt, and llms.txt
This commit is contained in:
@@ -283,15 +283,16 @@ export const useFeaturesStore = create<FeaturesState>((set, get) => {
|
||||
await refreshBundles();
|
||||
}
|
||||
|
||||
// Process the queue: re-read which bundles still need installing
|
||||
// (the one that was active may have just finished).
|
||||
// Process the queue sequentially. After each install, wait briefly
|
||||
// so the backend lock file is fully released before the next attempt.
|
||||
// If a bundle fails, re-enqueue it for one retry.
|
||||
const retried = new Set<string>();
|
||||
while (true) {
|
||||
const q = get().queued;
|
||||
if (q.length === 0) break;
|
||||
const nextId = q[0];
|
||||
set({ queued: q.slice(1) });
|
||||
|
||||
// Skip if it got installed in the meantime
|
||||
const current = get().bundles.find((b) => b.id === nextId);
|
||||
if (current?.status === "installed") continue;
|
||||
|
||||
@@ -299,6 +300,18 @@ export const useFeaturesStore = create<FeaturesState>((set, get) => {
|
||||
completionRefs[nextId] = resolve;
|
||||
get().installBundle(nextId);
|
||||
});
|
||||
await refreshBundles();
|
||||
|
||||
const after = get().bundles.find((b) => b.id === nextId);
|
||||
if (after?.status !== "installed" && !retried.has(nextId)) {
|
||||
retried.add(nextId);
|
||||
const errors = { ...get().errors };
|
||||
delete errors[nextId];
|
||||
set({ queued: [...get().queued, nextId], errors });
|
||||
}
|
||||
|
||||
// Brief pause to let the backend fully release the install lock
|
||||
await new Promise((r) => setTimeout(r, 2000));
|
||||
}
|
||||
|
||||
set({ queued: [], installAllActive: false });
|
||||
|
||||
Reference in New Issue
Block a user