diff --git a/README.md b/README.md index 3000e0e..425dc6c 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Source code for the /developer-tools portion of [Interledger.org](https://interl Inside this project, you'll see the following folders and files: -``` +```text . ├── public/ ├── src/ @@ -98,6 +98,23 @@ If you're unsure how to structure your writing, you can use this as a guide. Ideal Word Count: Between 1,000 and 2,500 words, with links to relevant documents/pages for a deeper understanding. +### Blog metadata and tags + +Each blog post includes frontmatter at the top of the file (title, description, date, authors, etc.), including a `tags` field used for filtering on the blog index. + +Please **only use the existing, approved tags** unless you have aligned with the tech + comms team on adding a new one. This helps keep the tag filter focused and avoids fragmentation. + +**Current tags:** + +- Interledger Protocol +- Open Payments +- Web Monetization +- Rafiki +- Updates +- Releases + +If you believe your post needs a new tag, propose it in your PR description or in the `#tech-team` Slack channel so we can decide whether to add it and update this list. + ### Getting Started Discuss Ideas: Before starting, share your blog post ideas with the tech team to ensure alignment and awareness. diff --git a/src/components/blog/BlogIndex.astro b/src/components/blog/BlogIndex.astro new file mode 100644 index 0000000..55cfdd8 --- /dev/null +++ b/src/components/blog/BlogIndex.astro @@ -0,0 +1,257 @@ +--- +import { createExcerpt } from '../../utils/create-excerpt' +import TagFilter from './TagFilter.astro' +import Pagination from './Pagination.astro' +import type { CollectionEntry } from 'astro:content' + +interface BreadcrumbItem { + name: string + href: string + umamiEvent: string +} + +interface Props { + title: string + posts: CollectionEntry<'blog'>[] + breadcrumbs?: BreadcrumbItem[] + allTags?: string[] + selectedTag?: string + showTagFilter?: boolean + showPagination?: boolean + paginationProps?: { + length: number + currentPage: number + firstUrl: string | undefined + prevUrl: string | undefined + nextUrl: string | undefined + lastUrl: string | undefined + } +} + +const { + title, + posts, + breadcrumbs = [], + allTags = [], + selectedTag, + showTagFilter = false, + showPagination = false, + paginationProps +} = Astro.props +--- + +
+
+ {breadcrumbs.length > 0 && ( + + )} +
+

{title}

+ +

Check out Foundation updates

+ +
+
+ {showTagFilter && } +
    + {posts.map((blogPostEntry) => { + const excerpt = `${createExcerpt(blogPostEntry.body).substring(0, 300)}...` + return ( +
  1. + + {blogPostEntry.data.lang ? ( + + ) : ( + + {blogPostEntry.data.title} + + )} +

    + {blogPostEntry.data.description + ? blogPostEntry.data.description + : excerpt} +

    +
  2. + ) + })} +
+ {showPagination && paginationProps && ( + + )} +
+
+ + + diff --git a/src/components/blog/TagFilter.astro b/src/components/blog/TagFilter.astro new file mode 100644 index 0000000..ea9d275 --- /dev/null +++ b/src/components/blog/TagFilter.astro @@ -0,0 +1,83 @@ +--- +import { getTagUrl } from '../../utils/tag-url' + +interface Props { + allTags: string[] + selectedTag?: string +} + +const { allTags, selectedTag } = Astro.props +--- + +
+
Filter by tag:
+
+ + All + + { + allTags.map((tag) => ( + + {tag} + + )) + } +
+
+ + diff --git a/src/content/blog/2018-01-29-simplifying-interledger-the-graveyard-of-possible-protocol-features.md b/src/content/blog/2018-01-29-simplifying-interledger-the-graveyard-of-possible-protocol-features.md index 1f551ce..900a670 100644 --- a/src/content/blog/2018-01-29-simplifying-interledger-the-graveyard-of-possible-protocol-features.md +++ b/src/content/blog/2018-01-29-simplifying-interledger-the-graveyard-of-possible-protocol-features.md @@ -9,8 +9,7 @@ author_urls: - https://www.linkedin.com/in/evanmarkschwartz/ external_url: https://medium.com/interledger-blog/simplifying-interledger-the-graveyard-of-possible-protocol-features-b35bf67439be tags: - - Interledger - - Interoperability + - Interledger Protocol --- As the development of the [Interledger Protocol](https://interledger.org/) (ILP) nears completion, I thought we should take a moment to remember some of the many core protocol features we’ve killed off along the way. diff --git a/src/content/blog/2018-10-03-interledger-how-to-interconnect-all-blockchains-and-value-networks.md b/src/content/blog/2018-10-03-interledger-how-to-interconnect-all-blockchains-and-value-networks.md index 27988d9..d07ca97 100644 --- a/src/content/blog/2018-10-03-interledger-how-to-interconnect-all-blockchains-and-value-networks.md +++ b/src/content/blog/2018-10-03-interledger-how-to-interconnect-all-blockchains-and-value-networks.md @@ -9,9 +9,7 @@ author_urls: - https://www.linkedin.com/in/evanmarkschwartz/ external_url: https://medium.com/xpring/interledger-how-to-interconnect-all-blockchains-and-value-networks-74f432e64543 tags: - - Interledger - - Connector - - Streaming Payments + - Interledger Protocol --- *By* [_Evan Schwartz_](https://www.linkedin.com/in/evanmarkschwartz/) *and* [_Vanessa Pestritto_](https://www.linkedin.com/in/vanessaalexandra/) diff --git a/src/content/blog/2019-01-23-thoughts-on-scaling-interledger-connectors.md b/src/content/blog/2019-01-23-thoughts-on-scaling-interledger-connectors.md index 869db5d..fd465c3 100644 --- a/src/content/blog/2019-01-23-thoughts-on-scaling-interledger-connectors.md +++ b/src/content/blog/2019-01-23-thoughts-on-scaling-interledger-connectors.md @@ -9,11 +9,7 @@ author_urls: - https://www.linkedin.com/in/evanmarkschwartz/ external_url: https://medium.com/interledger-blog/thoughts-on-scaling-interledger-connectors-7e3cad0dab7f tags: - - Interledger - - Connector - - Scaling - - Streaming Payments - - Internet Of Value + - Interledger Protocol --- Streaming payments mean that Interledger connectors need to process huge volumes of Interledger packets, but the current reference implementation is hard to run at scale. My hypothesis is that we should make the connector completely stateless using an HTTP-based bilateral communication protocol. diff --git a/src/content/blog/2024-04-10-the-telemetry-tale.md b/src/content/blog/2024-04-10-the-telemetry-tale.md index b46c74d..ddbbfd5 100644 --- a/src/content/blog/2024-04-10-the-telemetry-tale.md +++ b/src/content/blog/2024-04-10-the-telemetry-tale.md @@ -8,8 +8,8 @@ authors: author_urls: - https://www.linkedin.com/in/sarah-jones-ba6bb6b9 tags: - - Interledger - - Telemetry + - Interledger Protocol + - Updates --- ## Charting the Course @@ -45,7 +45,7 @@ We ran into a roadblock when we realized that AWS-managed Grafana does not allow Despite Grafana Cloud’s responsive support team, we also encountered issues adding the AWS-Managed Prometheus as a data source. Our [sigv4 authentication](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-signing.html) failed with a 403 Forbidden response, despite having the appropriate IAM permissions. The issue resolved spontaneously without clear intervention, implying an external factor (potentially AWS-side changes or maintenance) was at play. -You can view our public dashboard for test data telemetry [here](https://rafikitelemetry.grafana.net/public-dashboards/f70c8a6033b14da5a9f1cb974def602a). +You can view our public dashboard for test data telemetry on [Grafana Cloud](https://rafikitelemetry.grafana.net/public-dashboards/f70c8a6033b14da5a9f1cb974def602a). Here is an example of how it looks: diff --git a/src/content/blog/2024-07-09-simple-open-payments-guide.md b/src/content/blog/2024-07-09-simple-open-payments-guide.md index 85f6d77..f94c7f6 100644 --- a/src/content/blog/2024-07-09-simple-open-payments-guide.md +++ b/src/content/blog/2024-07-09-simple-open-payments-guide.md @@ -8,8 +8,8 @@ authors: author_urls: - https://www.linkedin.com/in/sarah-jones-ba6bb6b9 tags: - - Interledger - Open Payments + - Interledger Protocol --- ## The Current Digital Payments Landscape diff --git a/src/content/blog/2024-07-30-open-payments-cinderella-story.mdx b/src/content/blog/2024-07-30-open-payments-cinderella-story.mdx index 782ef68..039d313 100644 --- a/src/content/blog/2024-07-30-open-payments-cinderella-story.mdx +++ b/src/content/blog/2024-07-30-open-payments-cinderella-story.mdx @@ -8,9 +8,9 @@ authors: author_urls: - https://www.linkedin.com/in/nathan-lie-138a73121 tags: - - Interledger + - Interledger Protocol - Open Payments - - GNAP + - Updates --- import LargeImg from '/src/components/blog/LargeImg.astro' diff --git a/src/content/blog/2024-08-13-interledger-universe.mdx b/src/content/blog/2024-08-13-interledger-universe.mdx index 1c166a8..1f695af 100644 --- a/src/content/blog/2024-08-13-interledger-universe.mdx +++ b/src/content/blog/2024-08-13-interledger-universe.mdx @@ -9,16 +9,10 @@ authors: author_urls: - https://www.linkedin.com/in/sabineschaller tags: - - Interledger - Interledger Protocol - - Interledger Stack - - Interledger Foundation - Open Payments - Rafiki - - Dassie - Web Monetization - - STREAM - - SPSP --- If you have stumbled across terms like _Interledger Protocol, Interledger Stack, Interledger Foundation, Open Payments, Rafiki, Rafiki.money, Dassie, Web Monetization (extension), STREAM, SPSP, packets_, … and you are like and you're like, “Wait, what?!” Say no more! We are here to sort through this cloud of terms and finally shed some light on the foggiest depths of the Interledger Universe. Let’s start with the obvious first term: diff --git a/src/content/blog/2024-09-06-integration-tests.mdx b/src/content/blog/2024-09-06-integration-tests.mdx index edb67ad..713698b 100644 --- a/src/content/blog/2024-09-06-integration-tests.mdx +++ b/src/content/blog/2024-09-06-integration-tests.mdx @@ -8,9 +8,9 @@ authors: author_urls: - https://www.linkedin.com/in/blair-currey/ tags: - - Rafiki - Open Payments - - Testing + - Rafiki + - Interledger Protocol --- import LargeImg from '/src/components/blog/LargeImg.astro' diff --git a/src/content/blog/2024-09-23-rafiki-code-architecture.mdx b/src/content/blog/2024-09-23-rafiki-code-architecture.mdx index f85b2ae..c295497 100644 --- a/src/content/blog/2024-09-23-rafiki-code-architecture.mdx +++ b/src/content/blog/2024-09-23-rafiki-code-architecture.mdx @@ -9,6 +9,7 @@ author_urls: - https://www.linkedin.com/in/nathan-lie-138a73121 tags: - Rafiki + - Interledger Protocol --- import LargeImg from '/src/components/blog/LargeImg.astro' diff --git a/src/content/blog/2024-10-11-where-did-rafiki-money-go.mdx b/src/content/blog/2024-10-11-where-did-rafiki-money-go.mdx index e895cc2..fb913a0 100644 --- a/src/content/blog/2024-10-11-where-did-rafiki-money-go.mdx +++ b/src/content/blog/2024-10-11-where-did-rafiki-money-go.mdx @@ -8,7 +8,10 @@ authors: author_urls: - https://www.linkedin.com/in/nagy-timea-35483024 tags: - - Test Network + - Rafiki + - Interledger Protocol + - Open Payments + - Updates --- In the past few months we have come to know and love rafiki.money. So why did it disappear? Where did it go? diff --git a/src/content/blog/2024-10-25-rafikis-first-security-audit.mdx b/src/content/blog/2024-10-25-rafikis-first-security-audit.mdx index e43f12a..af0d16a 100644 --- a/src/content/blog/2024-10-25-rafikis-first-security-audit.mdx +++ b/src/content/blog/2024-10-25-rafikis-first-security-audit.mdx @@ -9,8 +9,8 @@ author_urls: - https://www.linkedin.com/in/mkurapov tags: - Rafiki - - security - - audit + - Interledger Protocol + - Updates --- At the beginning of the year, we were in contact with a security and penetration testing company to do an audit of Rafiki. Even though the software is still in its early stages, it is essential to gather feedback early to build a strong foundation for the software's security. The primary goals of the assessment were to evaluate several Rafiki components: the GraphQL Admin APIs, the frontend Admin UI component, as well as our underlying [ILPv4 protocol](https://interledger.org/developers/get-started/). The assessment was done using Rafiki’s local playground, based on the [Open Source Security Testing Methodology Manual (OSSTMM)](https://www.isecom.org/research.html) and [Open Source Web Application Security Project (OWASP)](https://owasp.org/) methodologies. diff --git a/src/content/blog/2024-12-03-e2e-testing-wm-browser-extension.mdx b/src/content/blog/2024-12-03-e2e-testing-wm-browser-extension.mdx index d307e25..00393d0 100644 --- a/src/content/blog/2024-12-03-e2e-testing-wm-browser-extension.mdx +++ b/src/content/blog/2024-12-03-e2e-testing-wm-browser-extension.mdx @@ -9,6 +9,7 @@ author_urls: - https://sidvishnoi.com?ref=ilf_engg_blog tags: - Web Monetization + - Interledger Protocol --- A sharp test suite anticipates problems, catching them before they surprise users. As developers, we often get a bit too familiar with our own code. With our inevitably biased views, we often end up overlooking issues from outlier scenarios, or usability considerations, all the way to the "oops" bugs. End-to-end tests help us view the product more objectively, from a user's perspective. Automating these tests saves time and ensures consistent quality throughout the development process. diff --git a/src/content/blog/2024-12-11-rafiki-beta-release.mdx b/src/content/blog/2024-12-11-rafiki-beta-release.mdx index 730133d..63ef2db 100644 --- a/src/content/blog/2024-12-11-rafiki-beta-release.mdx +++ b/src/content/blog/2024-12-11-rafiki-beta-release.mdx @@ -8,17 +8,12 @@ authors: author_urls: - https://www.linkedin.com/in/tadej-golobic tags: - - Interledger + - Releases - Interledger Protocol - - Interledger Stack - - Interledger Foundation - Open Payments - Rafiki - - Dassie - Web Monetization - - STREAM - - SPSP - - Beta + - Updates --- It is with great pride, and perhaps a touch of relief, that we deliver on a promise made: **[Rafiki Beta is here](https://github.com/interledger/rafiki/releases/tag/v1.0.0-beta)**. diff --git a/src/content/blog/2024-12-17-rafiki-tigerbeetle-integration.mdx b/src/content/blog/2024-12-17-rafiki-tigerbeetle-integration.mdx index a67aecc..9414f9d 100644 --- a/src/content/blog/2024-12-17-rafiki-tigerbeetle-integration.mdx +++ b/src/content/blog/2024-12-17-rafiki-tigerbeetle-integration.mdx @@ -9,13 +9,10 @@ author_urls: - https://github.com/koekiebox - https://www.linkedin.com/in/jason-bruwer-8110766/ tags: - - Interledger - Interledger Protocol - - Interledger Stack - - Interledger Foundation - Open Payments - Rafiki - - TigerBeetle + - Updates --- [Rafiki](https://rafiki.dev/) is an open-source platform that enables Account Servicing Entities (ASEs) like banks and digital wallet providers to integrate [Interledger Protocol](/developers/get-started) (ILP) functionality into their systems. diff --git a/src/content/blog/2025-02-05-ilp-packet-lifecycle.mdx b/src/content/blog/2025-02-05-ilp-packet-lifecycle.mdx index ec5f426..04d8fc8 100644 --- a/src/content/blog/2025-02-05-ilp-packet-lifecycle.mdx +++ b/src/content/blog/2025-02-05-ilp-packet-lifecycle.mdx @@ -8,7 +8,7 @@ authors: author_urls: - https://www.linkedin.com/in/nathan-lie-138a73121 tags: - - Interledger + - Interledger Protocol --- ## Introduction diff --git a/src/content/blog/2025-03-12-breakpoint-it-work-week.mdx b/src/content/blog/2025-03-12-breakpoint-it-work-week.mdx index 2fa7ad4..bce4ebd 100644 --- a/src/content/blog/2025-03-12-breakpoint-it-work-week.mdx +++ b/src/content/blog/2025-03-12-breakpoint-it-work-week.mdx @@ -8,7 +8,7 @@ authors: author_urls: - https://www.linkedin.com/in/nagy-timea-35483024 tags: - - Interledger + - Interledger Protocol --- After shaking off the January blues, the Interledger Engineering Managers and Product Managers gathered with the BreakPoint IT team for a productive work week in Cluj-Napoca, Romania. diff --git a/src/content/blog/2025-05-06-introducing-open-payments-php.mdx b/src/content/blog/2025-05-06-introducing-open-payments-php.mdx index 8716abb..227c9aa 100644 --- a/src/content/blog/2025-05-06-introducing-open-payments-php.mdx +++ b/src/content/blog/2025-05-06-introducing-open-payments-php.mdx @@ -8,9 +8,10 @@ authors: author_urls: - https://www.linkedin.com/in/adiboros/ tags: - - Interledger + - Releases + - Interledger Protocol - Open Payments - - PHP + - Updates --- ## 🎯 Why Open Payments Matters diff --git a/src/content/blog/2025-05-20-Introducing-publisher-tools.mdx b/src/content/blog/2025-05-20-Introducing-publisher-tools.mdx index 86054b4..280dd04 100644 --- a/src/content/blog/2025-05-20-Introducing-publisher-tools.mdx +++ b/src/content/blog/2025-05-20-Introducing-publisher-tools.mdx @@ -8,9 +8,10 @@ authors: author_urls: - https://www.linkedin.com/in/lengyel-arpad85/ tags: - - Interledger + - Releases + - Interledger Protocol + - Updates - Web Monetization - - publisher tools --- In a digital world where supporting content owners and publishers is becoming increasingly important, we wanted to build something that didn’t just preach the value of [Web Monetization](https://webmonetization.org/) - but made it accessible and easy for anyone to use. That’s how our [publisher tools](https://webmonetization.org/tools/) came to life. diff --git a/src/content/blog/2025-06-04-ES-El-Universo-Interledger.mdx b/src/content/blog/2025-06-04-ES-El-Universo-Interledger.mdx index b9d4acf..adf9c30 100644 --- a/src/content/blog/2025-06-04-ES-El-Universo-Interledger.mdx +++ b/src/content/blog/2025-06-04-ES-El-Universo-Interledger.mdx @@ -9,9 +9,8 @@ authors: author_urls: - https://www.linkedin.com/in/marianvilla/ tags: - - Interledger - - Pagos Abiertos - - Inclusión Financiera + - Interledger Protocol + - Open Payments --- > ⚠️ **Nota:** Este artículo es una adaptación al español. diff --git a/src/content/blog/2025-09-09-memorable-wallet-addresses-custom-domain.md b/src/content/blog/2025-09-09-memorable-wallet-addresses-custom-domain.md index 61b4089..98985a8 100644 --- a/src/content/blog/2025-09-09-memorable-wallet-addresses-custom-domain.md +++ b/src/content/blog/2025-09-09-memorable-wallet-addresses-custom-domain.md @@ -9,7 +9,6 @@ author_urls: - https://sidvishnoi.com?ref=ilf_engg_blog tags: - Open Payments - - Web Monetization --- Wallet addresses are meant to be easy to remember or identify, unless your wallet provider chooses them for you. The address might include a long subdomain or even a random series of numbers and characters. But did you know that if you own a domain, you can set your wallet address to be the same as your domain? diff --git a/src/content/blog/2025-09-30-wallet-address-smart-redirect.mdx b/src/content/blog/2025-09-30-wallet-address-smart-redirect.mdx index 2598718..65ad355 100644 --- a/src/content/blog/2025-09-30-wallet-address-smart-redirect.mdx +++ b/src/content/blog/2025-09-30-wallet-address-smart-redirect.mdx @@ -8,8 +8,10 @@ authors: author_urls: - https://www.linkedin.com/in/nodejs-dev/ tags: - - Interledger + - Releases + - Interledger Protocol - Rafiki + - Updates --- When you think of a **wallet address**, you probably think of a string of characters (or in Open Payments's case, a neat URL) that acts as a source or destination for payments. For example: diff --git a/src/pages/blog/[...page].astro b/src/pages/blog/[...page].astro index 00c99b9..d4c3ebe 100644 --- a/src/pages/blog/[...page].astro +++ b/src/pages/blog/[...page].astro @@ -1,22 +1,31 @@ --- -import { getCollection } from 'astro:content' import type { GetStaticPaths, Page } from 'astro' -import Pagination from '../../components/blog/Pagination.astro' import BaseLayout from '../../layouts/BaseLayout.astro' -import { createExcerpt } from '../../utils/create-excerpt' +import BlogIndex from '../../components/blog/BlogIndex.astro' +import { getCollection } from 'astro:content' type Props = { page: Page + allTags: string[] } export const getStaticPaths: GetStaticPaths = async ({ paginate }) => { const blogEntries = (await getCollection('blog')).sort( (a, b) => b.data.date.getTime() - a.data.date.getTime() ) - return paginate(blogEntries, { pageSize: 10 }) + + // Collect all unique tags + const allTags = [ + ...new Set(blogEntries.flatMap((entry) => entry.data.tags)) + ].sort() + + return paginate(blogEntries, { + pageSize: 10, + props: { allTags } + }) } -const { page } = Astro.props +const { page, allTags } = Astro.props --- -
-
- -
-

Engineering Blog

- -

Check out Foundation updates

- -
-
-
    - { - (page.data || []).map((blogPostEntry) => { - const excerpt = `${createExcerpt(blogPostEntry.body).substring(0, 300)}...` - return ( -
  1. - - {blogPostEntry.data.lang ? ( - - ) : ( - - {blogPostEntry.data.title} - - )} -

    - {blogPostEntry.data.description - ? blogPostEntry.data.description - : excerpt} -

    -
  2. - ) - }) - } -
- -
-
+
- - diff --git a/src/pages/blog/es.astro b/src/pages/blog/es.astro index 8f11009..b851ea3 100644 --- a/src/pages/blog/es.astro +++ b/src/pages/blog/es.astro @@ -1,9 +1,9 @@ --- import { getCollection } from 'astro:content' import BaseLayout from '../../layouts/BaseLayout.astro' -import { createExcerpt } from '../../utils/create-excerpt' +import BlogIndex from '../../components/blog/BlogIndex.astro' -// Only return posts with `draft: true` in the frontmatter +// Only return posts with `lang: 'es'` in the frontmatter const esEntries = await getCollection('blog', ({ data }) => { return data.lang === 'es' }) @@ -14,190 +14,20 @@ const esEntries = await getCollection('blog', ({ data }) => { description="Hear stories and experiences from the team who is working on making Interledger, the interoperable global payments network, a reality." ogImageUrl={new URL('/developers/img/blog/og-image.png', Astro.site).href} > -
-
- -
-

Blog de Ingeniería

- -

Check out Foundation updates

- -
-
-
    - { - esEntries.map((blogPostEntry) => { - const excerpt = `${createExcerpt(blogPostEntry.body).substring(0, 300)}...` - return ( -
  1. - - - {blogPostEntry.data.title} - -

    - {blogPostEntry.data.description - ? blogPostEntry.data.description - : excerpt} -

    -
  2. - ) - }) - } -
-
-
+ - - diff --git a/src/pages/blog/tag/[tag]/[...page].astro b/src/pages/blog/tag/[tag]/[...page].astro new file mode 100644 index 0000000..2749815 --- /dev/null +++ b/src/pages/blog/tag/[tag]/[...page].astro @@ -0,0 +1,76 @@ +--- +import type { Page } from 'astro' +import type { GetStaticPaths } from 'astro' +import { getTagSlug } from '../../../../utils/tag-url' +import BaseLayout from '../../../../layouts/BaseLayout.astro' +import BlogIndex from '../../../../components/blog/BlogIndex.astro' +import { getCollection } from 'astro:content' + +type Props = { + page: Page + allTags: string[] + selectedTag: string +} + +export const getStaticPaths: GetStaticPaths = async ({ paginate }) => { + const blogEntries = (await getCollection('blog')).sort( + (a, b) => b.data.date.getTime() - a.data.date.getTime() + ) + + // Collect all unique tags + const allTags = [ + ...new Set(blogEntries.flatMap((entry) => entry.data.tags)) + ].sort() + + // Create pages for each tag + return allTags.flatMap((tag) => { + const tagSlug = getTagSlug(tag) + const filteredEntries = blogEntries.filter((entry) => + entry.data.tags.includes(tag) + ) + + return paginate(filteredEntries, { + params: { tag: tagSlug }, + pageSize: 10, + props: { allTags, selectedTag: tag } + }) + }) +} + +const { page, allTags, selectedTag } = Astro.props +--- + + + + diff --git a/src/utils/tag-url.js b/src/utils/tag-url.js new file mode 100644 index 0000000..9c33143 --- /dev/null +++ b/src/utils/tag-url.js @@ -0,0 +1,19 @@ +/** + * Converts a tag name to a URL-friendly slug and returns the full tag URL path + * @param {string} tag - The tag name + * @returns {string} The tag URL path (e.g., "/developers/blog/tag/my-tag") + */ +export function getTagUrl(tag) { + const slug = tag.toLowerCase().replace(/\s+/g, '-') + return `/developers/blog/tag/${slug}` +} + +/** + * Converts a tag name to a URL-friendly slug + * @param {string} tag - The tag name + * @returns {string} The tag slug (e.g., "my-tag") + */ +export function getTagSlug(tag) { + return tag.toLowerCase().replace(/\s+/g, '-') +} +