react-helmet
react-helmet copied to clipboard
More complex title templates
Feature request
In my application I have a top-level Helmet
component which renders the default title, twitter and open graph meta tags. I have pages, each of which renders a Helmet
component with some custom text, and I have a global Navbar
which has the state of the unread notifications which I want to display in the title.
Essentially, I want my title to look like this: (1) Subpage | MyApp
.
The issue is that the title template doesn't allow me to have custom titles from the pages and also the unread notification count, so it'd show either Subpage | MyApp
or (1) | MyApp
, but I can't have both :cry:
Is there a way we could adapt the API to make more complex title theming possible? Would be happy to submit a PR if I get some pointers, or maybe I am missing some existing feature that makes this possible?
This would be pretty useful. Maybe it would help if nested <title>
can be combined in a way other than last-write-wins. First thought is to allow function child inside the tags.
For example.
<div>
<Helmet>
<title>MyApp</title>
</Helmet>
<Helmet>
<title>{prev => `Subpage | ${prev}`}</title>
</Helmet>
<Helmet>
<title>{prev => `(0) ${prev}`}</title>
</Helmet>
</div>
Then you can convert those into ordered list of title creators.
const titles = [
() => `MyApp`,
prev => `Subpage | ${prev}`,
prev => `(0) | ${prev}`
]
Which can be reduced down to a value.
titles.reduce((acc, f) => f(acc), '')
Note: If the last <title>
is a string s
, then it would exhibit the current behaviour of last-write-wins, since the last function reduced over is() => s
.
I like that! Would definitely solve my problem.
Interested in knowing what @cwelch5 thinks -- I'm not married to this idea. Seems to be some overlap with titleTemplate
, such as..
<div>
<Helmet titleTemplate="%s | MyApp" />
<Helmet>
<title>Subpage</title>
</Helmet>
</div>
Being roughly equivalent to:
<div>
<Helmet>
<title>MyApp</title>
</Helmet>
<Helmet>
<title>{prev => `Subpage | ${prev}`}</title>
</Helmet>
</div>
However, use cases like overriding titleTemplate
is not possible with functional <title>
.
More realistic scenario would be to use a function as the last <title>
rendered.
<div>
<Helmet titleTemplate="%s | MyApp" defaultTitle="MyApp" />
<Helmet>
<title>Subpage</title>
</Helmet>
<Helmet>
<title>{prev => `(0) ${prev}`}</title>
</Helmet>
</div>
Would be really interested in this as well, my use case is slightly simpler (I would like nested titleTemplate so my page title can be "Nested | Child | MainTitle") which comes from something like :
<div>
<Helmet titleTemplate="%s | MainTitle"` defaultTitle="MainTitle" />
<child>
<Helmet titleTemplate="%s | Child" defaultTitle="Child" />
<nested>
<Helmet title="Nested" />
</nested>
</child>
</div>
It would be really useful to have the nested capabilities like @jduthon said
can you add method title.toInnerText() or title.toComponent("%s | MyApp")?
Any progress on this?
I have exactly the same use case as @mxstbr, wanting to add unread notifications to my title!
@mxstbr @jaysoo Hey, I just published a tiny library react-titled that supports more complex nesting. It uses the new context API that comes with React 16.3.
You can use it as
import { Titled } from 'react-titled';
<Titled title={() => 'Example.com'}>
<h1>Welcome!</h1>
<Titled title={title => `Homepage | ${title}`} />
</Titled>;
outputs
Homepage | Example.com
Hope you find it useful. :)
react-helmet is still really great for other <head>
tags where composing is not needed. I think it doesn't make sense to dramatically change react-helmet's API to support that so I've create a new lib.
I'm assuming nothing like this ever got implemented? I have the exact same use case as others, wanting to put Unread Notifications in the title.
I've opened a PR for this here https://github.com/nfl/react-helmet/pull/541
My proposal works as follows:
https://github.com/nfl/react-helmet/blob/067a35c667e868cf2c49c390bd6ac7c429497b37/test/HelmetTest.js#L271-L280
=> Page Name | Section Name | Site Name
https://github.com/nfl/react-helmet/blob/067a35c667e868cf2c49c390bd6ac7c429497b37/test/HelmetTest.js#L297-L312
=> (1) Page Name | Section Name | Site Name
I'm still thinking if there's a clearer API/variable naming, but I think:
- for the template
A%sB
the API should allow insertion in to 4 points -1A2%s3B4
- the API should not be a breaking change, so when titleTemplate is a string it should override any previous nesting
Do you know if there is a 2020 solution for this kind of issues? using or not using Helmet??