Skip to content

Conversation

@RounakJoshi09
Copy link

@RounakJoshi09 RounakJoshi09 commented Oct 12, 2025

Linked Issue

Closes #1409

Description

This PR adds a tag-based filtering system to the resource section of the Virtual Coffee. With this enhancement, users can easily discover more targeted content by selecting tags that match their interests or preferred topics. The filtering logic is applied across all levels of the resource hierarchy, ensuring a consistent and intuitive experience throughout the platform.

Methodology

To support this feature, several updates were made, starting with enhancements to the core logic in loadMdx.server.ts.
The key change involves adding a new contentTags property to the MDX file interface. This property is populated during the recursive parsing of MDX files. As we parse the front matter of each MDX file, we extract the associated tags and assign them to the contentTags field, applying this to both individual files and directories.
Importantly, each parent MDX file will aggregate the tags from its own front matter as well as those of its child MDX files, ensuring comprehensive tag coverage for hierarchical filtering

The second major update in this PR involves the FileIndex.tsx component, which is responsible for rendering the content of each resource. Previously, this component handled server-side rendering only. Now, it has been enhanced to integrate a client-side component.

Since FileIndex.tsx remains a server-side component, we continue to load all directories for the target path using loadMdxDirectory, as before. Also, MDX files also being processed entirely on the server. This includes extracting all relevant Mdx Files and transforming them into post list items, eliminating the need for complex client-side conversions.

After completing these server-side computations, FileIndex.tsx renders a lazily loaded client-side wrapper component: tagFilteredResourceListWrapper.tsx. This wrapper dynamically loads the tagFilteredResourceList.tsx component, which handles the UI logic for tag filtering. It displays available tags, manages tag selection, and renders only the posts relevant to the selected tags.

I’ve also introduced a few new components to support the tag filtering functionality:

  • TagBatch: This component is responsible for rendering individual tags. It supports rendering tags as either buttons or spans, making it versatile for use in both the tag filtering interface and as inline tags displayed alongside each topic.

  • tagFilteredResourceList.tsx: This component encapsulates the core business logic for tag-based filtering. It manages the filtering state and renders the list of relevant topics using the PostList component based on the selected tags.

In addition to the component changes, I’ve introduced several utility functions to support tag filtering and organization:

  • extractContentTags: This helper function recursively traverses MDX files to extract tags from each MDX Files and there children. It ensures that each parent MDX file aggregates its own tags along with those of all its child MDX files, enabling comprehensive tag inheritance across the resource hierarchy.

  • tagCategories.ts: This utility is designed to group tags into meaningful categories. It includes helper functions such as organizeTagsByCategory , which streamline the process of classifying and displaying tags in a structured way.

This CSS file for the components has been included in tag-filter.scss, and a few changes in the CSS of post-list.scss have been made in order to view the relevant tags of the topics along with the header.

I’ve also made updates to the documentation to support the new content tagging system. Specifically:

  • I expanded the contributing.md file to include detailed guidance on the tagging mechanism—covering tag categories, how to add new tags, and best practices with examples.
  • Additionally, I created a separate tagging-guide.md that presents the same information in a more concise and focused format, highlighting tags and their categories in a quick-reference style.

Both documents are currently included to gather feedback and determine which format works best. Depending on team preference, we can either:

  1. Remove the tagging section from contributing.md, or
  2. Remove the standalone tagging-guide.md.

The goal is to retain whichever version offers the most clarity and usability for contributors.

Code of Conduct

By submitting this pull request, you agree to follow our Code of Conduct

…egorization

- Added contentTags to burnout, neurodiverse, asking coding questions, job-hunt with AI, and multiple open-source and virtual coffee handbook guides.
- Tags include beginner, intermediate, advanced, career, guide, and reference to enhance resource discoverability.
- Added contentTags property to MdxFile interface.
- Updated loadMdxDirectory function to aggregate contentTags from child MdxFiles, improving categorization and discoverability of content.
- Added a new utility function to recursively extract unique contentTags from an array of MdxFile objects and their children.
- This enhancement improves the ability to gather and categorize contentTags across multiple files.
- Enhanced PostItem interface to include the contentTags
- Build Component for TagBadges TagList and Separate Component to Render Posts in frontend using TagFilteredResourceList
- Modified Mdx Server to properly extract tags of the resources in sub directories to parent directories
@RounakJoshi09 RounakJoshi09 requested a review from a team as a code owner October 12, 2025 14:39
@netlify
Copy link

netlify bot commented Oct 12, 2025

👷 Deploy Preview for virtual-coffee-io processing.

Name Link
🔨 Latest commit 720e4ef
🔍 Latest deploy log https://app.netlify.com/projects/virtual-coffee-io/deploys/68ebc0fc57820c00087e8b46

…ments

- Added TagBadge component to display contentTags for each post in the PostList.
- Updated PostList styles to improve layout and responsiveness for post headers and tags.
- Introduced contentTags in the virtual coffee handbook resource for better categorization.
- Introduced tag categorization to improve the tag filtering UI, allowing users to expand and collapse categories.
- Implemented logic to auto-expand categories based on selected tags.
- Added new utility functions for organizing tags into categories and identifying uncategorized tags.
- Updated styles for better visual representation of tag categories and improved user interaction.
- Added 'ai' tag to the job-hunt with AI resource for improved categorization.
- Introduced a color palette for tag categories to enhance visual consistency in the tag management system.
- Updated existing tag categories to utilize the new color constants for better maintainability.
…ference

- Added a new section in CONTRIBUTING.md for a structured Content Tagging System to improve resource discoverability.
- Introduced TAGGING_GUIDE.md for quick reference on available tags, best practices, and examples.
- Updated layout.tsx to suppress hydration warnings for improved rendering consistency.
Copy link
Member

@danieltott danieltott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RounakJoshi09 this is really dope - great job!

I think the one major change I'd like to see - instead of keeping the post list and filter on the client-side, let's leverage nextjs. We can either do this via routing, or with search params.

A few reasons for this:

  • It lets us keep our index listings entirely server-side
  • It allows for bookmarking
  • It allows for the possibility in the future of pagination

We could also leverage this to include articles that aren't visible in the top layer. For instance, on the resources index page, we only go two levels deep. So when you choose "open source', we don't get any of the actual open source posts, just the open source top-level page.

If we were going to use routing, we could add a route like /resources/tag/[slug] where we'd do a split('_') on the slug. Urls would like like /resources/tag/open-source or resources/tag/open-source_intermediate. I think that might be a little messy though. Or, we could do a catch-all route like /resources/tag/[...slug] where urls would be like resources/tag/open-source/intermediate. That might work pretty well.

The search params option would be more straight-forward - /resources?tags[]=open-source&tags[]=intermediate. This would allow us to do this on any page that had FileIndex on it.

I'm still not sure really if we'd want to include all articles on a tag search or not. If so, we'd really want to have a dedicated route for tag search results, if not, we could do the searchParams method on every index route.

Either way we could support loading transitions etc - I think it'd work pretty well.

Two other much-smaller change I'd like to see:

  • Make the tags on the article lists clickable:
    image
  • Add tags to the actual articles:
    image

@RounakJoshi09
Copy link
Author

RounakJoshi09 commented Oct 14, 2025

Thanks for the feedback @danieltott , I really liked the idea, of using search params/routing as you suggested, I will brain strom further on this, and will try come up with a solution. I will take care of the other two feedbacks as well.
I hope you liked the UI of Filter By Tags area and how I categorized different tags.

Please do let me know if you have any other feedbacks.

@RounakJoshi09
Copy link
Author

RounakJoshi09 commented Oct 22, 2025

Hi @danieltott , I've been working on implementing server-side filtering for tags, but I’ve hit a snag. The issue is that when we use search params like this (/resources?tags=intermediate) , they’re accessible in page.tsx (src\app\resources[[...slug]]\page.tsx), which is great, we can forward them into an MDX component as <file.Component selectedTags={searchTags} /> However, the problem arises when trying to access those params inside src\components\content\FileIndex.tsx, which is the core component responsible for fetching and filtering posts.

The MDX files don’t seem to accept search params as props, so FileIndex.tsx can’t receive them directly. One workaround I considered is modifying all MDX files to accept search params explicitly as a prop, but that feels messy and redundant, especially since not every MDX file needs them. It also adds overhead for future MDX content.

Some alternative ideas I’ve thought about:

  • Using headers() in Next.js to read search params inside FileIndex.tsx, but that would make the component async, which might not be ideal. Because headers are available as promises in Next.js currently.
  • Injecting tags into headers via middleware, though that adds complexity and setup.

I’m looking for a clean and scalable way to pass search params into FileIndex.tsx without bloating the MDX layer. Any suggestions or best practices you’d recommend will be very very helpful?

Thanks in advance!

@danieltott
Copy link
Member

Hey @RounakJoshi09 - sorry it's taken me a bit to get back to this.

I thought about it for a while and poked around - I think the best bet is setting tags in headers in middleware and reading from there. The FileIndex component is already basically async by the time it gets to the TagFilteredResourceListWrapper because of the dynamic import, so that's probably ok.

This might give us a little more control over visuals, loading state, etc too. Give it a shot and let's check it out

@adiati98
Copy link
Contributor

Hey @RounakJoshi09,

I'm checking in here. How's the progress so far?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Hacktoberfest] Implement Tag Filtering System for Resources

3 participants