@@ -57,6 +57,8 @@ if (!rootElement) {
5757createRoot(rootElement).render(` ;
5858const VITE_REACT_BUTTON_PATTERN = "<button onClick={" ;
5959const VITE_REACT_BUTTON_REPLACEMENT = '<button type="button" onClick={' ;
60+ const VITE_REACT_DOCS_LINK_TEXT_PATTERN =
61+ / ( h r e f = " h t t p s : \/ \/ r e a c t \. d e v \/ " [ ^ > ] * > [ \s \S ] * ?) L e a r n m o r e ( [ \s \S ] * ?< \/ a > ) / ;
6062
6163export const up : MigrationUpFunction = async (
6264 absoluteProjectDir : string ,
@@ -188,6 +190,14 @@ function migrateCommonViteStarterFiles(absoluteProjectDir: string): void {
188190 join ( absoluteProjectDir , "src" , "App.tsx" ) ,
189191 migrateViteReactTsAppFile ,
190192 ) ;
193+ updateFileContent (
194+ join ( absoluteProjectDir , "public" , "favicon.svg" ) ,
195+ ( content ) => addTitleToSvg ( content , "Vite favicon" ) ,
196+ ) ;
197+ updateFileContent (
198+ join ( absoluteProjectDir , "public" , "icons.svg" ) ,
199+ ( content ) => addTitleToSvg ( content , "Vite icon sprite" ) ,
200+ ) ;
191201}
192202
193203function updateFileContent (
@@ -230,19 +240,45 @@ function migrateViteReactTsMainFile(content: string): string {
230240
231241function migrateViteReactTsAppFile ( content : string ) : string {
232242 return replaceExactPattern (
233- addRelNoopenerToBlankTargetLinks ( content ) ,
243+ replaceReactDocsLinkText ( addRelNoopenerToBlankTargetLinks ( content ) ) ,
234244 VITE_REACT_BUTTON_PATTERN ,
235245 VITE_REACT_BUTTON_REPLACEMENT ,
236246 ) ;
237247}
238248
249+ function replaceReactDocsLinkText ( content : string ) : string {
250+ return content . replace (
251+ VITE_REACT_DOCS_LINK_TEXT_PATTERN ,
252+ "$1Explore React docs$2" ,
253+ ) ;
254+ }
255+
239256function addRelNoopenerToBlankTargetLinks ( content : string ) : string {
240257 return content . replaceAll (
241258 / t a r g e t = " _ b l a n k " (? ! [ ^ > ] * \s r e l = ) / g,
242259 'target="_blank" rel="noopener"' ,
243260 ) ;
244261}
245262
263+ function addTitleToSvg ( content : string , title : string ) : string {
264+ if ( content . includes ( "<title>" ) ) {
265+ return content ;
266+ }
267+
268+ const openingTagMatch = content . match ( / ^ < s v g \b [ ^ > ] * > / ) ;
269+
270+ if ( ! openingTagMatch ) {
271+ return content ;
272+ }
273+
274+ const [ openingTag ] = openingTagMatch ;
275+ const titleMarkup = content . includes ( "\n" )
276+ ? `${ openingTag } \n <title>${ title } </title>`
277+ : `${ openingTag } <title>${ title } </title>` ;
278+
279+ return content . replace ( openingTag , titleMarkup ) ;
280+ }
281+
246282function replaceExactPattern (
247283 content : string ,
248284 pattern : string ,
0 commit comments