/Meteor-flow-router-title

Change document.title on the fly within flow-router

Primary LanguageJavaScriptBSD 3-Clause "New" or "Revised" LicenseBSD-3-Clause

support support

Reactive page title

Change document.title on the fly in Meteor.js apps via flow-router-extra API.

Features:

  • 👨‍🔬 100% tests coverage;
  • 🎛 Per route, per group, and default (all routes) title tag.

Various ways to set title, ordered by prioritization:

  • FlowRouter.route() [overrides all below]
  • FlowRouter.group()
  • FlowRouter.globals
  • Head template <title>Text</title> tag [might be overridden by any above]

Install:

meteor add ostrio:flow-router-title

Demos / Tests:

ES6 Import:

import { FlowRouterTitle } from 'meteor/ostrio:flow-router-title';

Related Packages:

Usage:

Initialize FlowRouterTitle class by passing FlowRouter object. Right after creating all routes:

import { FlowRouter }      from 'meteor/ostrio:flow-router-extra';
import { FlowRouterTitle } from 'meteor/ostrio:flow-router-title';

FlowRouter.route('/', {
  action() { /* ... */ },
  title: 'Title'
  /* ... */
});

new FlowRouterTitle(FlowRouter);

Set title via Route

Set title property in route's or group's configuration:

// Set default document.title value in
// case router has no title property
FlowRouter.globals.push({
  title: 'Default title'
});

FlowRouter.route('/me/account', {
  name: 'account',
  title: 'My Account'
});

.set() method

Set document.title during runtime (without route(s)):

FlowRouter.route('/', {/* ... */});

const titleHandler = new FlowRouterTitle(FlowRouter);
// `.set()` method accepts only String
titleHandler.set('My Awesome Title String'); // <- Returns `true`
titleHandler.set(() => { return 'Wrapped title'; }); // <- Returns `false`, as function can't be set into the `document.title`

Function context

Use function context (with data hook):

FlowRouter.route('/post/:_id', {
  name: 'post',
  waitOn(params) {
    return [Meteor.subscribe('post', params._id)];
  },
  data(params) {
    return Collections.Posts.findOne(params._id);
  },
  title(params, query, data) {
    if (data) {
      return data.title;
    }
    return '404: Page not found';
  }
});

Group context

Use group context:

const account = FlowRouter.group({
  prefix: '/account',
  title: 'Account',
  titlePrefix: 'Account > '
});

account.route('/', {
  name: 'accountIndex' // Title will be `Account`
});

account.route('/settings', {
  name: 'AccountSettings',
  title: 'My Settings' // Title will be `Account > My Settings`
});

Reactive data sources

To change title reactively, just pass it as function:

FlowRouter.route('/me/account', {
  name: 'account',
  title() {
    // In this example we used `ostrio:i18n` package
    return i18n.get('account.document.title');
  }
});

// Use params from route
FlowRouter.route('/page/:something', {
  name: 'somePage',
  title(params) {
    return 'Page ' + params.something;
  }
});

More examples

In all examples below title can be a Function or String:

import { FlowRouter } from 'meteor/ostrio:flow-router-extra';

FlowRouter.globals.push({
  title() {/* ... */} // <-- Suitable for reactive data source
});

FlowRouter.globals.push({
  title: 'Title text'
});

FlowRouter.group({
  title() {/* ... */}, // <-- Suitable for reactive data source
  titlePrefix() {/* ... */} // <-- Can accept reactive data source, but won't trigger re-computation
});

FlowRouter.group({
  title: 'Title text',
  titlePrefix: 'Title prefix text'
});

FlowRouter.route('/path', {
  title() {/* ... */} // <-- Reactive
});

FlowRouter.route('/path', {
  title: 'Title text'
});

Running Tests

  1. Clone this package
  2. In Terminal (Console) go to directory where package is cloned
  3. Then run:

Meteor/Tinytest

# Default
meteor test-packages ./

# With custom port
meteor test-packages ./ --port 8888

# With local MongoDB and custom port
MONGO_URL="mongodb://127.0.0.1:27017/flow-router-title-tests" meteor test-packages ./ --port 8888

Support this project: