After 2 weeks of evenings and weekends, I shipped Toolsfluent: a free hub of 35+ online tools (calculators, converters, generators) targeting privacy-conscious users in South Asia, the Gulf, and globally.
Sharing the technical learnings here, not the marketing version. If you're a solo dev shipping a content-heavy site, this might save you a few weeks.
The stack
- Framework: Next.js 15 (App Router, RSC, ISR)
- Language: TypeScript
- Styling: Tailwind CSS
- Icons: lucide-react
-
Fonts: Inter (body) + Sora (brand) via
next/font/google - Theme: next-themes
- Hosting: Vercel (Hobby tier)
Static generation for every tool page. No database. No auth. Currency converter is the only thing that hits an external API (exchangerate-api.com free tier).
What worked unexpectedly well
1. Single source-of-truth for tools
Every tool's metadata lives in one TypeScript array:
export const TOOLS: Tool[] = [
{
slug: "mortgage-calculator",
name: "Mortgage Calculator",
description: "...",
category: "finance",
keywords: [...],
icon: "Home",
featured: true,
howToSteps: [...],
faqs: [...],
relatedTools: [...]
},
// ... 34 more
];
Adding a new tool means: add the entry, create a folder, write the calculator component. Sitemap, JSON-LD schema, search index, navigation, related tools, and category pages auto-update from the array.
This single decision saved hours per tool. By tool 20, I was shipping new tools in under an hour.
2. JSON-LD structured data on everything
Every tool ships:
-
SoftwareApplicationschema -
FAQPageschema (from FAQs in the data array) BreadcrumbList
Categories ship CollectionPage. Site root ships WebSite + Organization.
Google takes JSON-LD seriously for tool pages. Without it, you're invisible. With it, your tool can show up with rating stars, FAQs in SERP, and "free" pricing badge.
Build a single buildToolJsonLd(tool) helper and you're done.
3. Per-tool meta description, canonical, OG tags via one helper
export function buildMetadata({title, description, path, keywords, image}) {
const url = `${SITE_URL}${path}`;
return {
title: `${title} | ${SITE_NAME}`,
description,
keywords: keywords.join(", "),
metadataBase: new URL(SITE_URL),
alternates: { canonical: url },
openGraph: {
title, description, url,
images: [{ url: image, width: 1200, height: 630 }]
},
twitter: { card: "summary_large_image" },
robots: { index: true, follow: true }
};
}
Every page calls this. Zero metadata bugs. Easy to verify in view-source.
What surprised me
Em-dashes flagged as AI content
Google's Helpful Content classifier flags em-dashes (—) as a strong signal of AI-generated content. Removed all of them site-wide via sed and replaced with commas / colons / periods. Sounds silly but it's a real ranking heuristic.
Authoritative source citations matter on YMYL
Every health and finance blog post got 2-3 citations to authoritative sources (CDC, WHO, NIST, IRS, CFPB, RBI, GST Council India, HMRC). YMYL (Your Money or Your Life) content without citations gets de-ranked by Google's Quality Rater Guidelines.
Took an extra hour per post to research and cite properly. Made a measurable difference in indexing speed.
Canonical tag with vs without trailing slash
Spent hours debugging "Alternate page with proper canonical tag" warnings in GSC. Turned out my SITE_URL had no trailing slash but Google was crawling URLs with trailing slash. Both worked but Google was confused which one to canonicalize.
Fix: be consistent. Pick one and stick with it everywhere.
Image compressor as a Canvas API trick
Most image compressors upload to a server. The privacy-first version is just:
const img = new Image();
img.onload = () => {
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
canvas.getContext('2d').drawImage(img, 0, 0);
canvas.toBlob(blob => downloadBlob(blob), 'image/jpeg', 0.8);
};
img.src = URL.createObjectURL(file);
Quality knob is just the third arg to toBlob. Done. No upload, no server, no privacy concerns.
What's next
- More Pakistani / Indian / UAE niche tools (Marla converter, UAE gratuity, Pakistani GPA already shipped)
- WhatsApp share button site-wide (huge in PK / IN, ignored by most western tool sites)
- AI-augmented text tools using Claude API (cover letter generator, code explainer, etc.) — text only, no image gen because paid API costs would exceed AdSense revenue at this stage
Honest numbers
35 tools live, 17 blog posts, all legal pages, GA4 + Bing + GSC verified. Indexed in Google within 24 hours of launch.
Traffic so far: a handful of visits from my own testing. Distribution is the next problem to solve, not the build.
If you want to see the production version: https://www.toolsfluent.com
Honest feedback welcome — especially on schema markup gotchas, perf optimization wins I'm missing, or tools you'd actually use.
United States
NORTH AMERICA
Related News
How Braze’s CTO is rethinking engineering for the agentic area
10h ago
Amazon Employees Are 'Tokenmaxxing' Due To Pressure To Use AI Tools
21h ago

Implementing Multicloud Data Sharding with Hexagonal Storage Adapters
15h ago

DeepMind’s CEO Says AGI May Be ~4 Years Away. The Last Three Missing Pieces Are Not What Most People Think.
15h ago

CCSnapshot - A Claude Code Configs Transfer Tool
21h ago