@@ -83,6 +83,57 @@ export class SeoService {
8383
8484 }
8585
86+ /**
87+ * Sets fallback meta tags when a blog post cannot be loaded.
88+ * This ensures social platforms show something useful instead of default home page tags.
89+ */
90+ setBlogSlugFallbackMetaTags ( slug : string ) : void {
91+
92+ const readableTitle = this . slugToReadableTitle ( slug ) ;
93+ const title = `${ readableTitle } - Kapil Garg` ;
94+ const url = `${ this . baseUrl } /blogs/${ slug } ` ;
95+ const description = `Read "${ readableTitle } " by Kapil Garg - Java Full Stack Developer sharing insights on technology, career, and software development.` ;
96+
97+ this . title . setTitle ( title ) ;
98+
99+ this . updateOrCreateMetaTag ( 'name' , 'description' , description ) ;
100+ this . updateOrCreateMetaTag ( 'name' , 'author' , this . author ) ;
101+ this . updateOrCreateMetaTag ( 'name' , 'keywords' , this . generateFallbackKeywords ( readableTitle ) ) ;
102+
103+ this . updateOrCreateMetaTag ( 'property' , 'og:type' , 'article' ) ;
104+ this . updateOrCreateMetaTag ( 'property' , 'og:title' , title ) ;
105+ this . updateOrCreateMetaTag ( 'property' , 'og:description' , description ) ;
106+ this . updateOrCreateMetaTag ( 'property' , 'og:image' , this . defaultImage ) ;
107+ this . updateOrCreateMetaTag ( 'property' , 'og:image:width' , '1200' ) ;
108+ this . updateOrCreateMetaTag ( 'property' , 'og:image:height' , '630' ) ;
109+ this . updateOrCreateMetaTag ( 'property' , 'og:image:alt' , title ) ;
110+ this . updateOrCreateMetaTag ( 'property' , 'og:image:type' , this . getImageType ( this . defaultImage ) ) ;
111+ this . updateOrCreateMetaTag ( 'property' , 'og:url' , url ) ;
112+ this . updateOrCreateMetaTag ( 'property' , 'og:site_name' , 'Kapil Garg' ) ;
113+ this . updateOrCreateMetaTag ( 'property' , 'og:locale' , 'en_US' ) ;
114+
115+ this . updateOrCreateMetaTag ( 'name' , 'twitter:card' , 'summary_large_image' ) ;
116+ this . updateOrCreateMetaTag ( 'name' , 'twitter:title' , title ) ;
117+ this . updateOrCreateMetaTag ( 'name' , 'twitter:description' , description ) ;
118+ this . updateOrCreateMetaTag ( 'name' , 'twitter:image' , this . defaultImage ) ;
119+ this . updateOrCreateMetaTag ( 'name' , 'twitter:site' , '@KappilGarg' ) ;
120+ this . updateOrCreateMetaTag ( 'name' , 'twitter:creator' , '@KappilGarg' ) ;
121+
122+ this . updateOrCreateLinkTag ( 'canonical' , url ) ;
123+ this . updateOrCreateMetaTag ( 'property' , 'article:author' , this . author ) ;
124+
125+ }
126+
127+ /**
128+ * Converts a URL slug to a readable title.
129+ */
130+ private slugToReadableTitle ( slug : string ) : string {
131+ return slug
132+ . split ( '-' )
133+ . map ( word => word . charAt ( 0 ) . toUpperCase ( ) + word . slice ( 1 ) . toLowerCase ( ) )
134+ . join ( ' ' ) ;
135+ }
136+
86137 setBlogsListingMetaTags ( ) : void {
87138 const title = 'Blogs - Kapil Garg' ;
88139 const url = `${ this . baseUrl } /blogs` ;
@@ -282,6 +333,11 @@ export class SeoService {
282333 return `${ categoryKeywords } ${ baseKeywords } ` ;
283334 }
284335
336+ private generateFallbackKeywords ( readableTitle : string ) : string {
337+ const baseKeywords = 'Kapil Garg, Java Developer, Full Stack Developer, Spring Boot, Angular, Blog' ;
338+ return `${ readableTitle } , ${ baseKeywords } ` ;
339+ }
340+
285341 private getImageType ( imageUrl : string ) : string {
286342 const sanitizedUrl = imageUrl . split ( '?' ) [ 0 ] ;
287343 const extension = sanitizedUrl . split ( '.' ) . pop ( ) ?. toLowerCase ( ) || 'png' ;
0 commit comments