From f220f1dd5ebd6c838572247ead2cbb542d684ed0 Mon Sep 17 00:00:00 2001 From: Andrew Zolotukhin Date: Wed, 8 Jul 2026 07:13:05 +0000 Subject: [PATCH 1/3] Add Toolfio footer badge --- apps/web/app/metadata-routes.test.ts | 5 ++- apps/web/components/landing-page.test.tsx | 36 +++++++++++++++++ apps/web/components/landing-page.tsx | 39 +++++++++++++++++++ .../web/content/blog/toolfio-footer-badge.mdx | 38 ++++++++++++++++++ 4 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 apps/web/content/blog/toolfio-footer-badge.mdx diff --git a/apps/web/app/metadata-routes.test.ts b/apps/web/app/metadata-routes.test.ts index 6b2da4c..c072d08 100644 --- a/apps/web/app/metadata-routes.test.ts +++ b/apps/web/app/metadata-routes.test.ts @@ -33,7 +33,7 @@ describe('metadata routes', () => { it('serves only public sitemap URLs', async () => { const urls = (await sitemap()).map(entry => entry.url); - expect(urls).toHaveLength(79); + expect(urls).toHaveLength(80); expect(urls).toEqual( expect.arrayContaining([ 'https://xpenser.cleverbrush.com/', @@ -53,7 +53,8 @@ describe('metadata routes', () => { 'https://xpenser.cleverbrush.com/blog/transaction-csv-export', 'https://xpenser.cleverbrush.com/blog/hide-amounts-mode', 'https://xpenser.cleverbrush.com/blog/period-aware-transaction-navigation', - 'https://xpenser.cleverbrush.com/blog/tag-report-transaction-drilldowns' + 'https://xpenser.cleverbrush.com/blog/tag-report-transaction-drilldowns', + 'https://xpenser.cleverbrush.com/blog/toolfio-footer-badge' ]) ); expect( diff --git a/apps/web/components/landing-page.test.tsx b/apps/web/components/landing-page.test.tsx index 4d9b2ab..95d05bd 100644 --- a/apps/web/components/landing-page.test.tsx +++ b/apps/web/components/landing-page.test.tsx @@ -177,6 +177,42 @@ describe('LandingPage', () => { expect(auraPlusPlusDarkBadgeImage?.className).toContain('hidden'); expect(auraPlusPlusDarkBadgeImage?.className).toContain('dark:block'); + const toolfioBadgeLink = screen.getByRole('link', { + name: /Featured on Toolfio/i + }); + expect(toolfioBadgeLink).toHaveProperty('href', 'https://toolfio.com/'); + expect(toolfioBadgeLink.getAttribute('target')).toBe('_blank'); + expect(toolfioBadgeLink.getAttribute('rel')).toBe( + 'dofollow noopener noreferrer' + ); + + const toolfioBadgeImages = screen.getAllByAltText( + 'Featured on Toolfio' + ); + expect(toolfioBadgeImages).toHaveLength(2); + + const toolfioLightBadgeImage = toolfioBadgeImages.find( + image => + image.getAttribute('src') === + 'https://toolfio.com/toolfio-light-badge.png' + ); + expect(toolfioLightBadgeImage).toBeTruthy(); + expect(toolfioLightBadgeImage?.getAttribute('width')).toBe('200'); + expect(toolfioLightBadgeImage?.getAttribute('height')).toBe('54'); + expect(toolfioLightBadgeImage?.className).toContain('block'); + expect(toolfioLightBadgeImage?.className).toContain('dark:hidden'); + + const toolfioDarkBadgeImage = toolfioBadgeImages.find( + image => + image.getAttribute('src') === + 'https://toolfio.com/toolfio-dark-badge.png' + ); + expect(toolfioDarkBadgeImage).toBeTruthy(); + expect(toolfioDarkBadgeImage?.getAttribute('width')).toBe('200'); + expect(toolfioDarkBadgeImage?.getAttribute('height')).toBe('54'); + expect(toolfioDarkBadgeImage?.className).toContain('hidden'); + expect(toolfioDarkBadgeImage?.className).toContain('dark:block'); + const openHuntsBadgeLink = screen.getByRole('link', { name: /OpenHunts Club Member/i }); diff --git a/apps/web/components/landing-page.tsx b/apps/web/components/landing-page.tsx index b66e9e5..b02f756 100644 --- a/apps/web/components/landing-page.tsx +++ b/apps/web/components/landing-page.tsx @@ -195,6 +195,15 @@ const auraPlusPlusBadge = { width: 265 } as const; +const toolfioBadge = { + alt: 'Featured on Toolfio', + darkSrc: 'https://toolfio.com/toolfio-dark-badge.png', + height: 54, + href: 'https://toolfio.com', + lightSrc: 'https://toolfio.com/toolfio-light-badge.png', + width: 200 +} as const; + const openHuntsBadge = { alt: 'OpenHunts Club Member', height: 105, @@ -608,6 +617,35 @@ function AuraPlusPlusBadge() { ); } +function ToolfioBadge() { + return ( + + {/* biome-ignore lint/performance/noImgElement: Toolfio provides this hosted badge snippet, and next/image would need remote config for a tiny footer badge. */} + {toolfioBadge.alt} + {/* biome-ignore lint/performance/noImgElement: Toolfio provides this hosted badge snippet, and next/image would need remote config for a tiny footer badge. */} + {toolfioBadge.alt} + + ); +} + function OpenHuntsBadge() { return ( + ); diff --git a/apps/web/content/blog/toolfio-footer-badge.mdx b/apps/web/content/blog/toolfio-footer-badge.mdx new file mode 100644 index 0000000..cd9c22e --- /dev/null +++ b/apps/web/content/blog/toolfio-footer-badge.mdx @@ -0,0 +1,38 @@ +--- +title: "Toolfio badge for xpenser discovery" +slug: toolfio-footer-badge +description: "xpenser added a Toolfio badge to the footer to support public discovery for the open-source personal finance app." +sourcePrNumber: "" +sourcePrUrl: "" +heroImage: "" +heroImageAlt: "" +publishedAt: 2026-07-08 +updatedAt: 2026-07-08 +targetKeyword: "open-source personal finance app discovery" +keywords: + - "open-source expense tracker" + - "personal finance app directory" + - "self-hosted personal finance tracker" + - "xpenser website" +draft: false +--- + +The xpenser footer gained a Toolfio badge as another lightweight discovery surface for people finding the project through software directories. + +This release adds Toolfio alongside the existing public discovery badges in the xpenser footer. It gives people evaluating an [open-source expense tracker](/open-source-expense-tracker) another route into the project while keeping the core application unchanged. + +## What changed + +- Added the Toolfio badge to public footer surfaces. +- Included light and dark badge variants so the image fits the active site theme. +- Preserved the existing public navigation and authenticated app behavior. + +## Why it matters + +Directory visibility is a practical part of early product distribution. A small footer badge can help people find xpenser while reinforcing the public site around the app. + +## Where it fits + +This is part of the public website and SEO layer around xpenser. + +For a broader product overview, start with the [xpenser home page](/). Developers can also explore the [personal finance API and MCP tools](/personal-finance-api-mcp), while self-hosters can review the [self-hosted personal finance tracker](/self-hosted-personal-finance-tracker) page. From 3c723f15cbab5cef6bfe1d89819309eb7501c095 Mon Sep 17 00:00:00 2001 From: Andrew Zolotukhin Date: Wed, 8 Jul 2026 07:15:28 +0000 Subject: [PATCH 2/3] Link Toolfio badge post to PR --- apps/web/content/blog/toolfio-footer-badge.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/web/content/blog/toolfio-footer-badge.mdx b/apps/web/content/blog/toolfio-footer-badge.mdx index cd9c22e..2fcb73a 100644 --- a/apps/web/content/blog/toolfio-footer-badge.mdx +++ b/apps/web/content/blog/toolfio-footer-badge.mdx @@ -2,8 +2,8 @@ title: "Toolfio badge for xpenser discovery" slug: toolfio-footer-badge description: "xpenser added a Toolfio badge to the footer to support public discovery for the open-source personal finance app." -sourcePrNumber: "" -sourcePrUrl: "" +sourcePrNumber: "68" +sourcePrUrl: "https://github.com/cleverbrush/xpenser/pull/68" heroImage: "" heroImageAlt: "" publishedAt: 2026-07-08 @@ -19,7 +19,7 @@ draft: false The xpenser footer gained a Toolfio badge as another lightweight discovery surface for people finding the project through software directories. -This release adds Toolfio alongside the existing public discovery badges in the xpenser footer. It gives people evaluating an [open-source expense tracker](/open-source-expense-tracker) another route into the project while keeping the core application unchanged. +This release came from [PR #68](https://github.com/cleverbrush/xpenser/pull/68) and adds Toolfio alongside the existing public discovery badges in the xpenser footer. It gives people evaluating an [open-source expense tracker](/open-source-expense-tracker) another route into the project while keeping the core application unchanged. ## What changed From f173d210e871ea9f930fd3279c9f3893a0e9930b Mon Sep 17 00:00:00 2001 From: Andrew Zolotukhin Date: Wed, 8 Jul 2026 07:39:01 +0000 Subject: [PATCH 3/3] Remove Toolfio badge blog post --- apps/web/app/metadata-routes.test.ts | 5 +-- .../web/content/blog/toolfio-footer-badge.mdx | 38 ------------------- 2 files changed, 2 insertions(+), 41 deletions(-) delete mode 100644 apps/web/content/blog/toolfio-footer-badge.mdx diff --git a/apps/web/app/metadata-routes.test.ts b/apps/web/app/metadata-routes.test.ts index c072d08..6b2da4c 100644 --- a/apps/web/app/metadata-routes.test.ts +++ b/apps/web/app/metadata-routes.test.ts @@ -33,7 +33,7 @@ describe('metadata routes', () => { it('serves only public sitemap URLs', async () => { const urls = (await sitemap()).map(entry => entry.url); - expect(urls).toHaveLength(80); + expect(urls).toHaveLength(79); expect(urls).toEqual( expect.arrayContaining([ 'https://xpenser.cleverbrush.com/', @@ -53,8 +53,7 @@ describe('metadata routes', () => { 'https://xpenser.cleverbrush.com/blog/transaction-csv-export', 'https://xpenser.cleverbrush.com/blog/hide-amounts-mode', 'https://xpenser.cleverbrush.com/blog/period-aware-transaction-navigation', - 'https://xpenser.cleverbrush.com/blog/tag-report-transaction-drilldowns', - 'https://xpenser.cleverbrush.com/blog/toolfio-footer-badge' + 'https://xpenser.cleverbrush.com/blog/tag-report-transaction-drilldowns' ]) ); expect( diff --git a/apps/web/content/blog/toolfio-footer-badge.mdx b/apps/web/content/blog/toolfio-footer-badge.mdx deleted file mode 100644 index 2fcb73a..0000000 --- a/apps/web/content/blog/toolfio-footer-badge.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: "Toolfio badge for xpenser discovery" -slug: toolfio-footer-badge -description: "xpenser added a Toolfio badge to the footer to support public discovery for the open-source personal finance app." -sourcePrNumber: "68" -sourcePrUrl: "https://github.com/cleverbrush/xpenser/pull/68" -heroImage: "" -heroImageAlt: "" -publishedAt: 2026-07-08 -updatedAt: 2026-07-08 -targetKeyword: "open-source personal finance app discovery" -keywords: - - "open-source expense tracker" - - "personal finance app directory" - - "self-hosted personal finance tracker" - - "xpenser website" -draft: false ---- - -The xpenser footer gained a Toolfio badge as another lightweight discovery surface for people finding the project through software directories. - -This release came from [PR #68](https://github.com/cleverbrush/xpenser/pull/68) and adds Toolfio alongside the existing public discovery badges in the xpenser footer. It gives people evaluating an [open-source expense tracker](/open-source-expense-tracker) another route into the project while keeping the core application unchanged. - -## What changed - -- Added the Toolfio badge to public footer surfaces. -- Included light and dark badge variants so the image fits the active site theme. -- Preserved the existing public navigation and authenticated app behavior. - -## Why it matters - -Directory visibility is a practical part of early product distribution. A small footer badge can help people find xpenser while reinforcing the public site around the app. - -## Where it fits - -This is part of the public website and SEO layer around xpenser. - -For a broader product overview, start with the [xpenser home page](/). Developers can also explore the [personal finance API and MCP tools](/personal-finance-api-mcp), while self-hosters can review the [self-hosted personal finance tracker](/self-hosted-personal-finance-tracker) page.