99} from "@/icons"
1010import { Card , Tag } from "@/components"
1111import NextLink from "next/link"
12+ import NextHead from "next/head"
1213import { useMounted } from "nextra/hooks"
1314import Markdown from "markdown-to-jsx"
1415import { evaluate } from "nextra/components"
@@ -66,16 +67,20 @@ export function CodePage({ allTags, data }: CodePageProps) {
6667 const [ search , setSearch ] = useState ( "" )
6768 const [ queryParamsTags , setTags ] = useQueryParam ( "tags" , TagParam )
6869
69- const handleQuery = useCallback ( ( e : MouseEvent < HTMLButtonElement > ) => {
70- const tag = e . currentTarget . dataset . tag !
70+ const handleQuery = useCallback (
71+ ( e : MouseEvent < HTMLAnchorElement | HTMLButtonElement > ) => {
72+ e . preventDefault ( )
73+ const tag = e . currentTarget . dataset . tag !
7174
72- setTags ( prevTags => {
73- if ( prevTags ! . includes ( tag ) ) {
74- return prevTags ! . filter ( t => t !== tag )
75- }
76- return [ ...prevTags ! , tag ]
77- } )
78- } , [ ] )
75+ setTags ( prevTags => {
76+ if ( prevTags ! . includes ( tag ) ) {
77+ return prevTags ! . filter ( t => t !== tag )
78+ }
79+ return [ ...prevTags ! , tag ]
80+ } )
81+ } ,
82+ [ setTags ] ,
83+ )
7984
8085 const mounted = useMounted ( )
8186 const [ isBackspacePressed , setIsBackspacePressed ] = useState ( false )
@@ -144,10 +149,37 @@ export function CodePage({ allTags, data }: CodePageProps) {
144149 }
145150 } , [ mounted , data , queryParamsTags ] )
146151
152+ const selectedTagsAsString = useMemo ( ( ) => {
153+ const tags = queryParamsTags
154+ . slice ( )
155+ . map ( tag => allTagsMap . get ( tag as string ) ?. name ?? tag )
156+ . filter ( ( tag ) : tag is string => typeof tag === "string" )
157+
158+ if ( tags . length === 0 ) {
159+ return ""
160+ }
161+
162+ if ( tags . length === 1 ) {
163+ return tags [ 0 ]
164+ }
165+
166+ return `${ tags . slice ( 0 , - 1 ) . join ( ", " ) } and ${ tags . slice ( - 1 ) [ 0 ] } `
167+ } , [ queryParamsTags , allTagsMap ] )
168+
147169 const [ sort , setSort ] = useState ( "popularity" )
148170
149171 return (
150172 < >
173+ < NextHead >
174+ < title >
175+ { selectedTagsAsString ? selectedTagsAsString + " | " : "" } Tools and
176+ Libraries | GraphQL
177+ </ title >
178+ < meta
179+ name = "description"
180+ content = { `A collection of tools and libraries for GraphQL${ selectedTagsAsString ? ` related to ${ selectedTagsAsString } ` : "" } ` }
181+ />
182+ </ NextHead >
151183 < div className = "container py-10 md:py-20" >
152184 < h1 className = "text-4xl md:text-7xl font-extrabold" >
153185 Code Using GraphQL
@@ -180,7 +212,8 @@ export function CodePage({ allTags, data }: CodePageProps) {
180212 ! search || name . toLowerCase ( ) . includes ( search . toLowerCase ( ) )
181213 if ( ! isTagMatchSearch ) return
182214 return (
183- < button
215+ < NextLink
216+ href = { `/community/tools-and-libraries/?tags=${ tag } ` }
184217 key = { tag }
185218 data-tag = { tag }
186219 className = { clsx (
@@ -193,7 +226,7 @@ export function CodePage({ allTags, data }: CodePageProps) {
193226 title = { `${ mounted && ( queryParamsTags as string [ ] ) . includes ( tag ) ? "Remove" : "Add" } tag "${ name } "` }
194227 >
195228 { name } ({ count } )
196- </ button >
229+ </ NextLink >
197230 )
198231 } ) }
199232 </ div >
@@ -287,7 +320,7 @@ export function CodePage({ allTags, data }: CodePageProps) {
287320 key = { tag }
288321 // @ts -expect-error -- fixme
289322 as = { NextLink }
290- href = { `/code ?tags=${ tag } ` }
323+ href = { `/community/tools-and-libraries/ ?tags=${ tag } ` }
291324 className = "hover:!bg-primary transition-colors hover:text-white cursor-pointer"
292325 >
293326 { allTagsMap . get ( tag ) ! . name }
@@ -351,6 +384,17 @@ const RemoteContent = memo(function RemoteContent({
351384 compiledSource : string
352385} ) {
353386 const { default : MDXContent } = evaluate ( compiledSource )
354- const components = getComponents ( { isRawLayout : false } )
387+ const components = getComponents ( {
388+ isRawLayout : false ,
389+ components : {
390+ // Rendering README.md with headings messes up the headings hierarchy of the page
391+ h1 : props => < strong { ...props } /> ,
392+ h2 : props => < strong { ...props } /> ,
393+ h3 : props => < strong { ...props } /> ,
394+ h4 : props => < strong { ...props } /> ,
395+ h5 : props => < strong { ...props } /> ,
396+ h6 : props => < strong { ...props } /> ,
397+ } ,
398+ } )
355399 return < MDXContent components = { components } />
356400} )
0 commit comments