CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-ember-page-title

Page title management for Ember.js applications with dynamic updates, FastBoot compatibility, and TypeScript support

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

typescript-integration.mddocs/

TypeScript Integration

Complete TypeScript definitions with Glint template registry and service registry integration for type-safe template and service usage.

Capabilities

Template Registry Integration

Glint template registry definitions for type-safe template usage.

/**
 * Template registry interface for Glint loose-mode templates
 */
interface LooseModeTemplateRegistry {
  /**
   * page-title helper used to set the title of the current route context
   */
  'page-title': typeof pageTitle;
}

Glint Setup:

// types/glint.d.ts
import '@glint/environment-ember-loose';
import '@glint/environment-ember-template-imports';

import type PageTitle from 'ember-page-title/template-registry';

declare module '@glint/environment-ember-loose/registry' {
  export default interface Registry extends PageTitle {
    // your local loose-mode entries here
  }
}

This provides type checking for template usage:

{{!-- Type-checked template usage --}}
{{page-title "My Title"}}
{{page-title @model.title separator=" - "}}
{{page-title "Settings" prepend=false replace=true}}

Service Registry Integration

Service registry definitions for type-safe service injection.

/**
 * Service registry interface for type-safe service injection
 */
interface ServiceRegistry {
  /**
   * The service for managing the title of the page
   */
  'page-title': PageTitleService;
  
  /**
   * ⚠️ This service is not provided by ember-page-title,
   *   but is needed by ember-page-title
   */
  '-document': FastBootDocument & { title?: string };
}

Service Registry Setup:

// types/ember.d.ts
import type PageTitle from 'ember-page-title/service-registry';

declare module '@ember/service' {
  interface Registry extends PageTitle {
    // your local service entries here
  }
}

Type-Safe Service Usage:

import Component from '@glimmer/component';
import { service } from '@ember/service';

export default class MyComponent extends Component {
  // Type-safe service injection
  @service('page-title') declare pageTitle: PageTitleService;
  
  updateTitle() {
    // TypeScript knows the shape of pageTitle service
    this.pageTitle.push({
      id: 'my-title',
      title: 'Type-Safe Title',
      separator: ' | '
    });
  }
}

Core Type Definitions

Complete type definitions for all API components.

/**
 * Configuration interface for page title defaults
 */
interface PageTitleConfig {
  /** The default separator to use between tokens */
  separator?: string;
  /** The default prepend value to use */
  prepend?: boolean;
  /** The default replace value to use */
  replace?: boolean | null;
}

/**
 * Token representing a page title segment with metadata
 */
interface PageTitleToken extends PageTitleConfig {
  /** Unique identifier for the token */
  id: string;
  /** The title text content */
  title?: string;
  /** Separator for this specific token */
  separator?: string;
  /** Whether to prepend this token */
  prepend?: boolean;
  /** Whether this token replaces others */
  replace?: boolean;
  /** Whether token goes at front regardless of order */
  front?: unknown;
  /** Reference to previous token in chain */
  previous?: PageTitleToken | null;
  /** Reference to next token in chain */
  next?: PageTitleToken | null;
}

/**
 * FastBoot document type for server-side rendering
 */
type FastBootDocument = ReturnType<typeof SimpleDomDocument> & {
  title?: string;
};

Helper Type Definitions

Type definitions for the template helper with full signature information.

/**
 * Options interface for page-title helper named parameters
 */
interface PageTitleHelperOptions {
  /** Whether to prepend or append the title token */
  prepend?: boolean;
  /** Whether token should always be at the beginning */
  front?: unknown;
  /** Whether to replace all previous tokens */
  replace?: boolean;  
  /** Separator to use after this token */
  separator?: string;
}

/**
 * Helper signature interface for type-safe template usage
 */
interface PageTitleHelperSignature {
  Args: {
    /** Positional arguments - title text segments */
    Positional: string[];
    /** Named arguments - configuration options */
    Named: PageTitleHelperOptions;
  };
  /** Helper returns void (side-effect only) */
  Return: void;
}

/**
 * Page title helper class with full type information
 */
class PageTitle extends Helper<PageTitleHelperSignature> {
  @service('page-title') declare tokens: PageTitleService;
  tokenId: string;
  
  constructor(owner: Owner);
  compute(params: string[], userOptions: PageTitleHelperOptions): string;
  willDestroy(): void;
}

Service Type Definitions

Complete type definitions for the page title service.

/**
 * Core page title service with full method signatures
 */
class PageTitleService extends Service {
  /** Array of all registered title tokens */
  tokens: PageTitleToken[];
  /** Default configuration applied to 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: PageTitleToken['id']): void;
  /** Schedule a title update on next run loop cycle */
  scheduleTitleUpdate(): void;
  /** Generate 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 */
  inheritFromPrevious(token: PageTitleToken): void;
  
  /** Get tokens that should be displayed */
  get visibleTokens(): PageTitleToken[];
  /** Get tokens in final display order */
  get sortedTokens(): PageTitleToken[];
  /** Called when service is destroyed - cleanup router listeners */
  willDestroy(): void;
}

Import Patterns

Type-safe import patterns for different usage scenarios.

// Main helper export (for gts/gjs)
import { pageTitle } from 'ember-page-title';

// Service class import
import PageTitleService from 'ember-page-title/services/page-title';

// Test support import
import { getPageTitle } from 'ember-page-title/test-support';

// Template registry import
import type TemplateRegistry from 'ember-page-title/template-registry';

// Service registry import  
import type ServiceRegistry from 'ember-page-title/service-registry';

// Direct type imports
import type { 
  PageTitleConfig, 
  PageTitleToken,
  PageTitleHelperOptions 
} from 'ember-page-title';

Manual Service Registration

For advanced scenarios where you want to manage service registration manually.

// Alternative to using service registry
import type PageTitleService from 'ember-page-title/services/page-title';

declare module '@ember/service' {
  interface Registry {
    'page-title': PageTitleService;
    // other services...
  }
}

Environment Configuration Typing

Type definitions for environment configuration.

/**
 * Environment configuration interface
 */
interface EmberEnvironment {
  pageTitle?: PageTitleConfig;
}

// Usage in config/environment.js
const ENV: EmberEnvironment = {
  pageTitle: {
    separator: ' | ',
    prepend: true,
    replace: false
  }
};

Install with Tessl CLI

npx tessl i tessl/npm-ember-page-title

docs

index.md

page-title-service.md

template-helper.md

test-support.md

typescript-integration.md

tile.json