or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.mdpage-title-service.mdtemplate-helper.mdtest-support.mdtypescript-integration.md
tile.json

page-title-service.mddocs/

Page Title Service

The page-title service provides programmatic control over title management with a token-based system, inheritance, and lifecycle hooks.

Capabilities

Page Title Service

Core service managing page title tokens and DOM updates.

/**
 * Service for managing page titles through a token-based system
 */
class PageTitleService extends Service {
  /** Array of all registered title tokens */
  tokens: PageTitleToken[];
  
  /** Default configuration for new tokens */
  _defaultConfig: PageTitleConfig;
  
  constructor(owner: Owner);
  
  /** Add or update a title token */
  push(token: PageTitleToken): void;
  
  /** Remove a token by its ID */
  remove(id: string): void;
  
  /** Schedule a title update on the next run loop cycle */
  scheduleTitleUpdate(): void;
  
  /** Generate the final title string from all tokens */
  toString(): string;
  
  /** Hook called after title updates (override in subclass) */
  titleDidUpdate(title: string): void;
  
  /** Update title in FastBoot environment */
  updateFastbootTitle(title: string): void;
  
  /** Apply default configuration to a token */
  applyTokenDefaults(token: PageTitleToken): void;
  
  /** Inherit properties from previous token in chain */
  inheritFromPrevious(token: PageTitleToken): void;
  
  /** Get tokens that should be displayed (respects replace behavior) */
  get visibleTokens(): PageTitleToken[];
  
  /** Get tokens in final display order (respects front, prepend, append) */
  get sortedTokens(): PageTitleToken[];
  
  /** Called when service is destroyed - cleanup router listeners */
  willDestroy(): void;
}

Service Usage:

import Component from '@glimmer/component';
import { service } from '@ember/service';
import type PageTitleService from 'ember-page-title/services/page-title';

export default class MyComponent extends Component {
  @service('page-title') declare pageTitle: PageTitleService;
  
  updateTitle() {
    // Add a title token programmatically
    this.pageTitle.push({
      id: 'my-component-title',
      title: 'Dynamic Title',
      separator: ' - ',
      prepend: true
    });
  }
  
  removeTitle() {
    // Remove a specific token
    this.pageTitle.remove('my-component-title');
  }
}

Token Management

The service manages titles through a token-based system with automatic ordering and inheritance.

/**
 * Add or update a title token in the service
 * @param token - Token to add or update
 */
push(token: PageTitleToken): void;

/**
 * Remove a token by its unique ID
 * @param id - Unique identifier of token to remove
 */
remove(id: string): void;

/**
 * Schedule a title update on the next afterRender run loop cycle
 */
scheduleTitleUpdate(): void;

Token System Examples:

// Add a basic token
this.pageTitle.push({
  id: 'main-title',
  title: 'My Application',
  separator: ' | '
});

// Add a token that replaces others
this.pageTitle.push({
  id: 'error-title', 
  title: 'Error Occurred',
  replace: true
});

// Add a token that always goes first
this.pageTitle.push({
  id: 'priority-title',
  title: 'URGENT',
  front: true
});

// Remove a specific token
this.pageTitle.remove('main-title');

Title Generation

The service generates final title strings through a sophisticated ordering and inheritance system.

/**
 * Generate the final title string from all tokens
 * @returns Complete title string ready for DOM
 */
toString(): string;

/**
 * Get tokens that should be displayed (respects replace behavior)
 * @returns Array of visible tokens
 */
get visibleTokens(): PageTitleToken[];

/**
 * Get tokens in final display order
 * @returns Array of tokens in display order
 */  
get sortedTokens(): PageTitleToken[];

Title Composition Logic:

  1. Visibility: Tokens marked with replace: true hide previous tokens
  2. Ordering: Tokens are sorted by front, prepend, and append behavior
  3. Joining: Final string joins token titles with their separators
// Example token processing
const tokens = [
  { id: '1', title: 'Home', separator: ' | ' },
  { id: '2', title: 'Products', separator: ' | ' }, 
  { id: '3', title: 'Laptop', separator: '' }
];

// Result: "Home | Products | Laptop"
console.log(this.pageTitle.toString());

Lifecycle Hooks

The service provides hooks for custom integration and monitoring.

/**
 * Hook called after title updates - override for custom behavior
 * @param title - The new title that was set
 */
titleDidUpdate(title: string): void;

Custom Service Extension:

// app/services/page-title.js
import PageTitleService from 'ember-page-title/services/page-title';

export default class extends PageTitleService {
  titleDidUpdate(title) {
    super.titleDidUpdate(title);
    
    // Custom logic after title changes
    console.log('Title updated:', title);
    
    // Track analytics
    if (window.gtag) {
      window.gtag('config', 'GA_MEASUREMENT_ID', {
        page_title: title
      });
    }
    
    // Update meta tags
    document.querySelector('meta[property="og:title"]')
      ?.setAttribute('content', title);
  }
}

Configuration and Defaults

The service applies configurable defaults to new tokens.

/**
 * Apply default configuration to a token
 * @param token - Token to apply defaults to
 */
applyTokenDefaults(token: PageTitleToken): void;

/**
 * Inherit properties from previous token in chain
 * @param token - Token to inherit properties for
 */
inheritFromPrevious(token: PageTitleToken): void;

/** Default configuration for new tokens */
_defaultConfig: PageTitleConfig;

Default Configuration:

The service reads defaults from config/environment.js:

// config/environment.js
module.exports = function(environment) {
  return {
    pageTitle: {
      separator: ' | ',  // Default separator
      prepend: true,     // Default prepend behavior
      replace: null      // Default replace behavior
    }
  };
};

FastBoot Integration

The service automatically handles server-side rendering environments.

/** 
 * Update title in FastBoot environment
 * @param title - Title to set in server context
 */
updateFastbootTitle(title: string): void;

FastBoot Features:

  • Automatic environment detection
  • Server-side DOM title element management
  • Compatible with FastBoot document API
  • Proper title element cleanup and creation