Freud
It gets in your head
Freud is an head
manager for React applications. It supports server-rendering and thus is compatible with your SPAs or any other amenity.
Freud is inspired by react-helmet, but it's a far simpler implementation (which is largely possible thanks to the awesome react-side-effect).
Example
import React from 'react';import Freud form 'freud'; /* the tag renders as null and sets the provided properties *//* properties on tags which appear later/deeper in the render tree override previous tags */const OEdipus = <div> <Freud ="I've got a problem" /> <Freud ="Maybe two" /> "Mom is best ❤️" </div>; const Mother = <div> <Freud ="OEdipus news | %s" = /> </div>; ReactDOM;
Usage
Install it the npm
-way:
npm install react-freud --save
You'll need also react
as peerDependencies
.
<Freud prop=value />
It's just a normal component which renders to null
but does some magic at render time. The fact it renders to null
means it swallows all its children so don't use it as a wrapper component.
title
: sets the title of the page.defaultTitle
: if notitle
is set, this becomes the title, otherwise it's overridden (low-precedencetitle
).titleTemplate
: a format string where%s
gets replaced by thetitle
(in the example above, the page title will be OEdipus news | Maybe two).links
: an array of PJOs whom attributes will be set on<link>
tags. Arrays are not overridden but merged, for instance in the above example Freud will addvienna.css
andthebes.css
(preserves order). However, if you add two identical objects (identical == deeply equal), Freud will only load one.scripts
: same semantics oflinks
, but creates<script>
tags.metas
: same semantics oflinks
, but creates<meta>
tags.
To do the actual modifications to head
there are two options:
- Use the
syncHere
attribute on aFreud
tag (see example). When this component is rendered, thehead
state will be synced with all the options set until now. So use this only if you want to force some rendering or you are 100% sure this is the lastFreud
tag that is rendered - Use the
sync
method ofFreud
, which does the same thing. - Use withFreudSync HoC component which automatically calls
Freud.sync()
whenever its children change. This is the most effective way, especially if you're using routing: just wrap your top components with it:
import withFreudSync from 'react-freud'; <Router> <Route = ="/foo" /> <Route = ="/bar" /></Router>
Why all this trouble?
Because of the way react-side-effect
works, Freud
cannot know if the properties encountered until now are complete or something is missing. So if I sync head every time a Freud
tag is rendered, I could unmount some tag which is required by a Freud
tag deeper in the render tree.
In particular, by doing this Freud
works fine with server-side rendering.
On the serve, use the amazing rewind()
function to get the tags to put in your head
.
import Freud from 'freud'; const html = ReactDOM; const title scripts links metas = Freud; ;
It's actually required to use rewind()
on server-side to avoid memory leaks. See react-side-effect documentation.
If you rehydrate your React app client-side, you should call Freud.sync()
after the app gets re-rendered.
A good place is the ReactDOM.render()
callback:
ReactDOM;
Which is called every time the App
component is updated. If during the lifecycle of your app some components dynamically render Freud
tags, remember to call Freud.sync()
.
Contribution
Typical npm
workflow:
git clone https://github.com/mattecapu/freud.git
cd freud
NODE_ENV=development npm i
npm run dev
License
ISC