@@ -32,7 +32,32 @@ export interface MetaContextType {
3232
3333const cascadingTags = [ "title" , "meta" ] ;
3434
35- const getTagType = ( tag : TagDescription ) => tag . tag + ( tag . name ? `.${ tag . name } "` : "" ) ;
35+ // https://html.spec.whatwg.org/multipage/semantics.html#the-title-element
36+ const titleTagProperties : string [ ] = [ ] ;
37+
38+ const metaTagProperties : string [ ] =
39+ // https://html.spec.whatwg.org/multipage/semantics.html#the-meta-element
40+ [ "name" , "http-equiv" , "content" , "charset" , "media" ]
41+ // additional properties
42+ . concat ( [ "property" ] ) ;
43+
44+ const getTagKey = ( tag : TagDescription , properties : string [ ] ) => {
45+ // pick allowed properties and sort them
46+ const tagProps = Object . fromEntries (
47+ Object . entries ( tag . props )
48+ . filter ( ( [ k ] ) => properties . includes ( k ) )
49+ . sort ( )
50+ ) ;
51+
52+ // treat `property` as `name` for meta tags
53+ if ( Object . hasOwn ( tagProps , "name" ) || Object . hasOwn ( tagProps , "property" ) ) {
54+ tagProps . name = tagProps . name || tagProps . property ;
55+ delete tagProps . property ;
56+ }
57+
58+ // concat tag name and properties as unique key for this tag
59+ return tag . tag + JSON . stringify ( tagProps ) ;
60+ } ;
3661
3762const MetaProvider : ParentComponent < { tags ?: Array < TagDescription > } > = props => {
3863 if ( ! isServer && ! sharedConfig . context ) {
@@ -71,21 +96,22 @@ const MetaProvider: ParentComponent<{ tags?: Array<TagDescription> }> = props =>
7196
7297 const actions : MetaContextType = {
7398 addClientTag : ( tag : TagDescription ) => {
74- let tagType = getTagType ( tag ) ;
75-
7699 if ( cascadingTags . indexOf ( tag . tag ) !== - 1 ) {
100+ const properties = tag . tag === "title" ? titleTagProperties : metaTagProperties ;
101+ const tagKey = getTagKey ( tag , properties ) ;
102+
77103 // only cascading tags need to be kept as singletons
78- if ( ! cascadedTagInstances . has ( tagType ) ) {
79- cascadedTagInstances . set ( tagType , [ ] ) ;
104+ if ( ! cascadedTagInstances . has ( tagKey ) ) {
105+ cascadedTagInstances . set ( tagKey , [ ] ) ;
80106 }
81107
82- let instances = cascadedTagInstances . get ( tagType ) ;
108+ let instances = cascadedTagInstances . get ( tagKey ) ;
83109 let index = instances . length ;
84110
85111 instances = [ ...instances , tag ] ;
86112
87113 // track indices synchronously
88- cascadedTagInstances . set ( tagType , instances ) ;
114+ cascadedTagInstances . set ( tagKey , instances ) ;
89115
90116 if ( ! isServer ) {
91117 let element = getElement ( tag ) ;
@@ -127,10 +153,11 @@ const MetaProvider: ParentComponent<{ tags?: Array<TagDescription> }> = props =>
127153 } ,
128154
129155 removeClientTag : ( tag : TagDescription , index : number ) => {
130- const tagName = getTagType ( tag ) ;
156+ const properties = tag . tag === "title" ? titleTagProperties : metaTagProperties ;
157+ const tagKey = getTagKey ( tag , properties ) ;
131158
132159 if ( tag . ref ) {
133- const t = cascadedTagInstances . get ( tagName ) ;
160+ const t = cascadedTagInstances . get ( tagKey ) ;
134161 if ( t ) {
135162 if ( tag . ref . parentNode ) {
136163 tag . ref . parentNode . removeChild ( tag . ref ) ;
@@ -142,7 +169,7 @@ const MetaProvider: ParentComponent<{ tags?: Array<TagDescription> }> = props =>
142169 }
143170
144171 t [ index ] = null ;
145- cascadedTagInstances . set ( tagName , t ) ;
172+ cascadedTagInstances . set ( tagKey , t ) ;
146173 } else {
147174 if ( tag . ref . parentNode ) {
148175 tag . ref . parentNode . removeChild ( tag . ref ) ;
@@ -157,11 +184,11 @@ const MetaProvider: ParentComponent<{ tags?: Array<TagDescription> }> = props =>
157184 const { tags = [ ] } = props ;
158185 // tweak only cascading tags
159186 if ( cascadingTags . indexOf ( tagDesc . tag ) !== - 1 ) {
160- const index = tags . findIndex ( prev => {
161- const prevName = prev . props . name || prev . props . property ;
162- const nextName = tagDesc . props . name || tagDesc . props . property ;
163- return prev . tag === tagDesc . tag && prevName === nextName ;
164- } ) ;
187+ const properties = tagDesc . tag === "title" ? titleTagProperties : metaTagProperties ;
188+ const tagDescKey = getTagKey ( tagDesc , properties ) ;
189+ const index = tags . findIndex (
190+ prev => prev . tag === tagDesc . tag && getTagKey ( prev , properties ) === tagDescKey
191+ ) ;
165192 if ( index !== - 1 ) {
166193 tags . splice ( index , 1 ) ;
167194 }
0 commit comments