mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix: replace hardcoded "52 tools" with "50+" across all copy
Future-proofs marketing text so it doesn't need updating every time a tool is added.
This commit is contained in:
+2
-2
@@ -5,8 +5,8 @@ Live demo, per-tool landing pages, and a batch of polish fixes.
|
||||
## New features
|
||||
|
||||
- **Live demo** -- [demo.snapotter.com](https://demo.snapotter.com) lets people try SnapOtter without installing anything.
|
||||
- **Tools index page** -- Browse all 52 tools at `/tools` with search and category filters. Navbar links fixed on subpages.
|
||||
- **52 SEO landing pages** -- Every tool now has a dedicated landing page with FAQs, use cases, and comparison tables for search visibility.
|
||||
- **Tools index page** -- Browse all 50+ tools at `/tools` with search and category filters. Navbar links fixed on subpages.
|
||||
- **50+ SEO landing pages** -- Every tool now has a dedicated landing page with FAQs, use cases, and comparison tables for search visibility.
|
||||
- **Background preview** -- Before-after slider shows a checkered background behind transparent images so you can actually see what changed.
|
||||
- **Strong password generator** -- One-click button in the Add Members form generates a secure password.
|
||||
- **Easter eggs** -- Hello from the otter side.
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
## Key Features
|
||||
|
||||
- **52 image tools:** Resize, crop, compress, convert, watermark, color adjust, beautify screenshots, generate memes, vectorize, create GIFs, find duplicates, generate passport photos, and more. Supports 55+ input formats (including 23 camera RAW formats) and 14 output formats
|
||||
- **50+ image tools:** Resize, crop, compress, convert, watermark, color adjust, beautify screenshots, generate memes, vectorize, create GIFs, find duplicates, generate passport photos, and more. Supports 55+ input formats (including 23 camera RAW formats) and 14 output formats
|
||||
- **Image editor:** Layer-based editor with brushes, shapes, adjustments, filters, curves, and keyboard shortcuts. Runs in your browser, processes on your hardware
|
||||
- **Local AI:** Remove backgrounds, upscale images, restore and colorize old photos, erase objects, blur faces, enhance faces, extract text (OCR), expand canvas, fix transparency. All on your hardware, no internet required
|
||||
- **OIDC / SSO:** Login with Google, GitHub, Okta, or any OpenID Connect provider
|
||||
|
||||
@@ -39,7 +39,7 @@ function generateLlmsTxt(spec: OpenAPISpec): string {
|
||||
lines.push(`# ${spec.info.title}`);
|
||||
lines.push("");
|
||||
lines.push(
|
||||
"> Self-hosted image processing API with 52 tools. Resize, compress, convert, remove backgrounds, upscale, run OCR, and more.",
|
||||
"> Self-hosted image processing API with 50+ tools. Resize, compress, convert, remove backgrounds, upscale, run OCR, and more.",
|
||||
);
|
||||
lines.push("");
|
||||
lines.push("## Docs");
|
||||
|
||||
@@ -11,8 +11,8 @@ Live demo, per-tool landing pages, and a batch of polish fixes.
|
||||
### New features
|
||||
|
||||
- **Live demo** -- [demo.snapotter.com](https://demo.snapotter.com) lets people try SnapOtter without installing anything.
|
||||
- **Tools index page** -- Browse all 52 tools at `/tools` with search and category filters.
|
||||
- **52 SEO landing pages** -- Every tool now has a dedicated landing page with FAQs, use cases, and comparison tables.
|
||||
- **Tools index page** -- Browse all 50+ tools at `/tools` with search and category filters.
|
||||
- **50+ SEO landing pages** -- Every tool now has a dedicated landing page with FAQs, use cases, and comparison tables.
|
||||
- **Background preview** -- Before-after slider shows a checkered background behind transparent images.
|
||||
- **Strong password generator** -- One-click button in the Add Members form.
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ Shared TypeScript types, constants (like `APP_VERSION` and tool definitions), an
|
||||
|
||||
### API (`apps/api`)
|
||||
|
||||
A Fastify v5 server exposing 52 tool routes (36 standard image operations + 16 AI-powered) that handles:
|
||||
A Fastify v5 server exposing 50+ tool routes (36 standard image operations + 16 AI-powered) that handles:
|
||||
- File uploads, temporary workspace management, and persistent file storage
|
||||
- User file library with version chains (`user_files` table) -- each processed result links back to its source file and records which tool was applied, with auto-generated thumbnails for the Files page
|
||||
- Tool execution (routes each tool request to the image engine or AI bridge)
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ layout: home
|
||||
hero:
|
||||
name: "SnapOtter"
|
||||
text: "A Self Hosted Image Manipulator"
|
||||
tagline: 52 tools. Local AI. No cloud. Your images never leave your home.
|
||||
tagline: 50+ tools. Local AI. No cloud. Your images never leave your home.
|
||||
actions:
|
||||
- theme: brand
|
||||
text: Get started
|
||||
|
||||
@@ -8,7 +8,7 @@ const nunito = Nunito({ subsets: ["latin"], variable: "--font-nunito" });
|
||||
export const metadata: Metadata = {
|
||||
title: "SnapOtter | Self-Hosted Image Processing",
|
||||
description:
|
||||
"52 image processing tools with local AI. Runs 100% offline. No data leaves your network. Open source and free forever.",
|
||||
"50+ image processing tools with local AI. Runs 100% offline. No data leaves your network. Open source and free forever.",
|
||||
metadataBase: new URL("https://snapotter.com"),
|
||||
icons: {
|
||||
icon: [
|
||||
@@ -24,7 +24,7 @@ export const metadata: Metadata = {
|
||||
openGraph: {
|
||||
title: "SnapOtter | Self-Hosted Image Processing",
|
||||
description:
|
||||
"52 image processing tools with local AI. Runs 100% offline. No data leaves your network.",
|
||||
"50+ image processing tools with local AI. Runs 100% offline. No data leaves your network.",
|
||||
url: "https://snapotter.com",
|
||||
siteName: "SnapOtter",
|
||||
type: "website",
|
||||
@@ -43,7 +43,7 @@ export const metadata: Metadata = {
|
||||
site: "@SnapOtterHQ",
|
||||
title: "SnapOtter | Self-Hosted Image Processing",
|
||||
description:
|
||||
"52 image processing tools with local AI. Runs 100% offline. No data leaves your network.",
|
||||
"50+ image processing tools with local AI. Runs 100% offline. No data leaves your network.",
|
||||
images: ["/og-image.png"],
|
||||
},
|
||||
};
|
||||
|
||||
@@ -21,7 +21,7 @@ const websiteJsonLd = {
|
||||
name: "SnapOtter",
|
||||
url: "https://snapotter.com",
|
||||
description:
|
||||
"52 image processing tools with local AI. Runs 100% offline. No data leaves your network.",
|
||||
"50+ image processing tools with local AI. Runs 100% offline. No data leaves your network.",
|
||||
publisher: {
|
||||
"@type": "Organization",
|
||||
name: "SnapOtter",
|
||||
@@ -44,7 +44,7 @@ const softwareJsonLd = {
|
||||
"@type": "SoftwareApplication",
|
||||
name: "SnapOtter",
|
||||
description:
|
||||
"52 image processing tools with local AI. Runs 100% offline. No data leaves your network. Open source and free forever.",
|
||||
"50+ image processing tools with local AI. Runs 100% offline. No data leaves your network. Open source and free forever.",
|
||||
applicationCategory: "MultimediaApplication",
|
||||
operatingSystem: "Linux, macOS, Windows (via Docker)",
|
||||
offers: {
|
||||
|
||||
@@ -392,7 +392,7 @@ export default async function ToolPage({ params }: PageProps) {
|
||||
Ready to try {tool.name}?
|
||||
</h2>
|
||||
<p className="mx-auto mt-4 max-w-lg text-muted">
|
||||
Deploy SnapOtter in under a minute. All 52 tools included. Open source and free
|
||||
Deploy SnapOtter in under a minute. All 50+ tools included. Open source and free
|
||||
forever.
|
||||
</p>
|
||||
<div className="mt-8 flex flex-wrap justify-center gap-4">
|
||||
|
||||
@@ -36,7 +36,7 @@ export function BentoGrid() {
|
||||
<div className="mx-auto max-w-6xl">
|
||||
<FadeIn>
|
||||
<h2 className="font-[family-name:var(--font-nunito)] text-center text-3xl font-bold tracking-tight md:text-4xl">
|
||||
52 tools. Zero cloud dependency.
|
||||
50+ tools. Zero cloud dependency.
|
||||
</h2>
|
||||
<p className="mx-auto mt-4 max-w-xl text-center text-lg text-muted">
|
||||
Search to find exactly what you need. Every tool runs 100% locally.
|
||||
|
||||
@@ -119,7 +119,7 @@ export function Hero() {
|
||||
</h1>
|
||||
|
||||
<p className="mt-4 animate-[fadeUp_0.6s_ease-out_0.1s_both] text-base text-muted md:text-lg">
|
||||
A free, open-source image toolkit with 52 tools that runs entirely on your network.
|
||||
A free, open-source image toolkit with 50+ tools that runs entirely on your network.
|
||||
</p>
|
||||
|
||||
<p className="mt-4 animate-[fadeUp_0.6s_ease-out_0.2s_both] text-xl font-medium md:text-2xl">
|
||||
|
||||
@@ -7,7 +7,7 @@ const freePlan = {
|
||||
price: "Free",
|
||||
subtitle: "For everyone. Forever.",
|
||||
features: [
|
||||
"All 52 image processing tools",
|
||||
"All 50+ image processing tools",
|
||||
"Unlimited usage, no hidden caps",
|
||||
"Full REST API with OpenAPI docs",
|
||||
"Pipeline automation",
|
||||
|
||||
@@ -11,7 +11,7 @@ const phrases = [
|
||||
"No limits. No hidden caps.",
|
||||
"Works fully offline.",
|
||||
"Unlimited batch processing.",
|
||||
"52 image tools.",
|
||||
"50+ image tools.",
|
||||
"16 AI models. Your hardware.",
|
||||
"Lightning fast. Built on Sharp.",
|
||||
"Air-gapped ready.",
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
"name": "snapotter",
|
||||
"version": "1.17.1",
|
||||
"private": true,
|
||||
"description": "Self-hosted image processing suite with 52 tools and local AI. Single Docker container, no external services.",
|
||||
"description": "Self-hosted image processing suite with 50+ tools and local AI. Single Docker container, no external services.",
|
||||
"homepage": "https://snapotter.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1611,7 +1611,7 @@ export const en = {
|
||||
heading: "About",
|
||||
appName: "SnapOtter",
|
||||
appDescription:
|
||||
"A self-hosted, privacy-first image processing suite with 52 tools. Resize, compress, convert, watermark, and automate your image workflows without sending data to the cloud.",
|
||||
"A self-hosted, privacy-first image processing suite with 50+ tools. Resize, compress, convert, watermark, and automate your image workflows without sending data to the cloud.",
|
||||
versionLabel: "Version:",
|
||||
linksHeading: "Links",
|
||||
githubLink: "GitHub Repository",
|
||||
@@ -1654,7 +1654,7 @@ export const en = {
|
||||
"No limits. No hidden caps.",
|
||||
"Works fully offline.",
|
||||
"Unlimited batch processing.",
|
||||
"52 image tools.",
|
||||
"50+ image tools.",
|
||||
"16 AI models. Your hardware.",
|
||||
"Lightning fast. Built on Sharp.",
|
||||
"Air-gapped ready.",
|
||||
|
||||
@@ -1667,7 +1667,7 @@ export const nl: TranslationKeys = {
|
||||
heading: "Over",
|
||||
appName: "SnapOtter",
|
||||
appDescription:
|
||||
"Een zelf-gehoste, privacy-first beeldverwerkingssuite met 52 tools. Schalen, comprimeren, converteren, watermerken en je beeldworkflows automatiseren zonder data naar de cloud te sturen.",
|
||||
"Een zelf-gehoste, privacy-first beeldverwerkingssuite met 50+ tools. Schalen, comprimeren, converteren, watermerken en je beeldworkflows automatiseren zonder data naar de cloud te sturen.",
|
||||
versionLabel: "Versie:",
|
||||
linksHeading: "Links",
|
||||
githubLink: "GitHub-repository",
|
||||
|
||||
@@ -13,7 +13,7 @@ test.describe("Docs Homepage", () => {
|
||||
await expect(page.getByText("SnapOtter").first()).toBeVisible();
|
||||
await expect(page.getByText("A Self Hosted Image Manipulator")).toBeVisible();
|
||||
await expect(
|
||||
page.getByText("52 tools. Local AI. No cloud. Your images never leave your home."),
|
||||
page.getByText("50+ tools. Local AI. No cloud. Your images never leave your home."),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ test.describe("Landing Homepage", () => {
|
||||
});
|
||||
|
||||
test("bento grid renders with search and tool count", async ({ page }) => {
|
||||
await expect(page.getByText("52 tools. Zero cloud dependency.")).toBeVisible();
|
||||
await expect(page.getByText("50+ tools. Zero cloud dependency.")).toBeVisible();
|
||||
await expect(page.getByPlaceholder("Search tools...")).toBeVisible();
|
||||
await expect(page.getByText(/Showing 52 of 52 tools/)).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -47,7 +47,7 @@ function generateLlmsTxt(spec: OpenAPISpec): string {
|
||||
lines.push(`# ${spec.info.title}`);
|
||||
lines.push("");
|
||||
lines.push(
|
||||
"> Self-hosted image processing API with 52 tools. Resize, compress, convert, remove backgrounds, upscale, run OCR, and more.",
|
||||
"> Self-hosted image processing API with 50+ tools. Resize, compress, convert, remove backgrounds, upscale, run OCR, and more.",
|
||||
);
|
||||
lines.push("");
|
||||
lines.push("## Docs");
|
||||
|
||||
@@ -25,7 +25,7 @@ function getCountText(): string {
|
||||
describe("BentoGrid", () => {
|
||||
it("renders the section heading", () => {
|
||||
render(<BentoGrid />);
|
||||
expect(screen.getByText("52 tools. Zero cloud dependency.")).toBeDefined();
|
||||
expect(screen.getByText("50+ tools. Zero cloud dependency.")).toBeDefined();
|
||||
});
|
||||
|
||||
it("renders the search input", () => {
|
||||
|
||||
@@ -157,7 +157,7 @@ describe("Pricing", () => {
|
||||
|
||||
it("renders free plan features", () => {
|
||||
render(<Pricing />);
|
||||
expect(screen.getByText("All 52 image processing tools")).toBeDefined();
|
||||
expect(screen.getByText("All 50+ image processing tools")).toBeDefined();
|
||||
expect(screen.getByText("Unlimited usage, no hidden caps")).toBeDefined();
|
||||
expect(screen.getByText("15 local AI models included")).toBeDefined();
|
||||
expect(screen.getByText("AGPL-3.0 licensed")).toBeDefined();
|
||||
|
||||
Reference in New Issue
Block a user