Skip to content

Commit 115671c

Browse files
authored
Release v0.4.1
2 parents dd14223 + 5278cf9 commit 115671c

4 files changed

Lines changed: 35 additions & 20 deletions

File tree

.changeset/famous-ideas-share.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@devsantara/head': patch
3+
---
4+
5+
fix(add-title): default title should show without the template

README.md

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -176,28 +176,23 @@ Set a title template with a default value, then pass page-specific titles as str
176176
import { HeadBuilder } from '@devsantara/head';
177177

178178
// Create a builder and set title template with default
179-
// The template stays active for all future addTitle() calls
180-
const sharedHead = new HeadBuilder().addTitle({
179+
// The default value is used initially, template is stored for future use
180+
const baseHead = new HeadBuilder().addTitle({
181181
template: '%s | My Awesome site', // Store template (%s is the placeholder)
182-
default: 'Home', // Initial title using template
182+
default: 'Home', // Initial title (template not applied yet)
183183
});
184-
// Output: <title>Home | My Awesome site</title>
184+
// Output: <title>Home</title>
185185

186186
// Update title for Posts page
187187
// Pass a string, builder applies the saved template automatically
188-
const postHead = sharedHead.addTitle('Posts').build();
188+
const postHead = baseHead.addTitle('Posts').build();
189189
// Output: <title>Posts | My Awesome site</title>
190-
191-
// Update title for About page
192-
// Template is still active from the first addTitle() call
193-
const aboutHead = sharedHead.addTitle('About Us').build();
194-
// Output: <title>About Us | My Awesome site</title>
195190
```
196191

197192
**How it works:**
198193

199-
1. First `addTitle()` with template object stores the template internally
200-
2. Subsequent `addTitle()` calls with strings automatically use the stored template
194+
1. First `addTitle()` with template object stores the template internally and uses just the default value
195+
2. Subsequent `addTitle()` calls with strings automatically apply the stored template
201196
3. The `%s` placeholder gets replaced with your page title
202197
4. Each title replaces the previous one (deduplication)
203198

src/builder.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,8 @@ export class HeadBuilder<TOutput = HeadElement[]> {
327327
* Adds a title element that appears in browser tabs, search results, and bookmarks.
328328
* Supports both simple string titles and templated titles with dynamic substitution.
329329
*
330+
* When a template is provided via TitleOptions, the default is used initially and the template is applied to subsequent string titles.
331+
*
330332
* @param title - The document title as a string, or TitleOptions object with template and default
331333
* @returns The builder instance for method chaining
332334
*
@@ -338,9 +340,11 @@ export class HeadBuilder<TOutput = HeadElement[]> {
338340
*
339341
* @example
340342
* // Templated title with page-specific suffix
343+
* // Setting the template with default stores 'Home' as the title
341344
* const baseHead = new HeadBuilder()
342-
* .addTitle({ template: '%s | My Site', default: 'Home' })
345+
* .addTitle({ template: '%s | My Site', default: 'Home' });
343346
*
347+
* // Subsequent string titles apply the template
344348
* const head = baseHead.addTitle('About Us').build(); // Results in title "About Us | My Site"
345349
*/
346350
addTitle(title: string | TitleOptions): this {
@@ -360,12 +364,10 @@ export class HeadBuilder<TOutput = HeadElement[]> {
360364

361365
/**
362366
* If title is provided as an object with template and default,
363-
* we store the options and generate the title using the template with default.
367+
* we store the options and add the default title. Subsequent calls with string titles will use the template for generation.
364368
*/
365369
this.titleOptions = title;
366-
this.addElement('title', {
367-
children: this.titleOptions.template.replace('%s', title.default),
368-
});
370+
this.addElement('title', { children: this.titleOptions.default });
369371
return this;
370372
}
371373

src/tests/builder-add-title.test.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ describe('HeadBuilder.addTitle', () => {
1919

2020
expect(result[0]).toEqual({
2121
type: 'title',
22-
attributes: { children: 'Home | My Site' },
22+
attributes: { children: 'Home' },
2323
});
2424
});
2525

@@ -36,15 +36,28 @@ describe('HeadBuilder.addTitle', () => {
3636
});
3737
});
3838

39-
it('should update template when new template is set', () => {
39+
it('should update template when new template is set (default template)', () => {
4040
const result = new HeadBuilder()
4141
.addTitle({ template: '%s | Site A', default: 'Home' })
4242
.addTitle({ template: '%s | Site B', default: 'Index' })
4343
.build();
4444

4545
expect(result[0]).toEqual({
4646
type: 'title',
47-
attributes: { children: 'Index | Site B' },
47+
attributes: { children: 'Index' },
48+
});
49+
});
50+
51+
it('should update template when new template is set (full template)', () => {
52+
const result = new HeadBuilder()
53+
.addTitle({ template: '%s | Site A', default: 'Home' })
54+
.addTitle({ template: '%s | Site B', default: 'Index' })
55+
.addTitle('Contact')
56+
.build();
57+
58+
expect(result[0]).toEqual({
59+
type: 'title',
60+
attributes: { children: 'Contact | Site B' },
4861
});
4962
});
5063

0 commit comments

Comments
 (0)