@@ -102,15 +102,16 @@ function parseTeddyDOMFromString (html) {
102102 } else {
103103 // handle tags
104104 const [ fullMatch , tagName , attrString ] = match
105+ const lowerCaseTagName = tagName . toLowerCase ( )
105106 const isClosingTag = fullMatch . startsWith ( '</' )
106107 if ( isClosingTag ) {
107- if ( selfClosingTags . has ( tagName . toLowerCase ( ) ) ) {
108+ if ( selfClosingTags . has ( lowerCaseTagName ) ) {
108109 // convert incorrect closing tag for self-closing tag to self-closing tag
109110 const element = document . createElement ( tagName )
110111 dom [ dom . length - 1 ] . appendChild ( element )
111112 } else {
112113 // check if the closing tag matches the most recent open tag
113- if ( openTags . length > 0 && openTags [ openTags . length - 1 ] === tagName . toLowerCase ( ) ) {
114+ if ( openTags . length > 0 && openTags [ openTags . length - 1 ] === lowerCaseTagName ) {
114115 openTags . pop ( )
115116 dom . pop ( )
116117 }
@@ -141,7 +142,24 @@ function parseTeddyDOMFromString (html) {
141142 // apply attributes to the element
142143 for ( const [ name , value ] of attrMap ) {
143144 try {
144- element . setAttribute ( name , value || '' )
145+ // replace elements with `src` attributes with `data-teddy-defer-attr-src` so the browser doesn't try to prefetch the asset
146+ // this is needed because the value of the `src` attribute could be a {teddyVariable} and that fetch won't resolve
147+ switch ( lowerCaseTagName ) {
148+ case 'img' :
149+ case 'video' :
150+ case 'audio' :
151+ case 'iframe' :
152+ case 'script' :
153+ if ( name === 'src' ) element . setAttribute ( 'data-teddy-defer-attr-src' , value ) // replace src with data-teddy-defer-attr-src
154+ else element . setAttribute ( name , value || '' )
155+ break
156+ case 'link' :
157+ if ( name === 'href' ) element . setAttribute ( 'data-teddy-defer-attr-href' , value ) // replace src with data-teddy-defer-attr-href
158+ else element . setAttribute ( name , value || '' )
159+ break
160+ default :
161+ element . setAttribute ( name , value || '' )
162+ }
145163 } catch ( e ) {
146164 console . warn ( 'Error parsing an element attribute. You might have a typo in your HTML. A common cause is two spaces between element attributes.' )
147165 }
@@ -151,9 +169,9 @@ function parseTeddyDOMFromString (html) {
151169 dom [ dom . length - 1 ] . appendChild ( element )
152170
153171 // push the new element to the dom if it's not self-closing
154- if ( ! selfClosingTags . has ( tagName . toLowerCase ( ) ) && ! fullMatch . endsWith ( '/>' ) ) {
172+ if ( ! selfClosingTags . has ( lowerCaseTagName ) && ! fullMatch . endsWith ( '/>' ) ) {
155173 dom . push ( element )
156- openTags . push ( tagName . toLowerCase ( ) )
174+ openTags . push ( lowerCaseTagName )
157175 }
158176 }
159177 }
0 commit comments