Skip to content

Commit

Permalink
fix(core): remove componentWillMount warning with react-helmet-async
Browse files Browse the repository at this point in the history
  • Loading branch information
luisherranz committed Sep 9, 2019
1 parent d1de357 commit 0ea885b
Show file tree
Hide file tree
Showing 13 changed files with 77 additions and 29 deletions.
Expand Up @@ -37,7 +37,7 @@ Array [
`;

exports[`Image works on server 2`] = `
"<script data-react-helmet=\\"true\\" id=\\"frontity-no-proxy-images\\" type=\\"text/javascript\\">
"<script data-rh=\\"true\\" id=\\"frontity-no-proxy-images\\" type=\\"text/javascript\\">
if (typeof window !== \\"undefined\\" && (!(\\"Proxy\\" in window) || !(\\"IntersectionObserver\\" in window))) {
document.addEventListener(\\"DOMContentLoaded\\", function() {
var images = document.querySelectorAll(\\"img.frontity-lazy-image\\");
Expand All @@ -55,7 +55,7 @@ exports[`Image works on server 2`] = `
`;
exports[`Image works on server 3`] = `
"<noscript data-react-helmet=\\"true\\" ><style id=\\"frontity-no-js-images\\" type=\\"text/css\\">
"<noscript data-rh=\\"true\\" ><style id=\\"frontity-no-js-images\\" type=\\"text/css\\">
:not(noscript) > .frontity-lazy-image {
display: none;
}
Expand Down
5 changes: 3 additions & 2 deletions packages/components/__tests__/image.jsdom.tests.tsx
@@ -1,3 +1,4 @@
/* eslint-disable no-global-assign */
/**
* @jest-environment jsdom
*/
Expand Down Expand Up @@ -52,7 +53,7 @@ describe("Image", () => {
state: { frontity: { rendering: "ssr" } }
};

let result = TestRenderer.create(<Image {...props} />);
const result = TestRenderer.create(<Image {...props} />);
expect(result.toJSON()).toMatchSnapshot();
});

Expand All @@ -69,7 +70,7 @@ describe("Image", () => {
state: { frontity: { rendering: "csr" } }
};

let result = TestRenderer.create(<Image {...props} />);
const result = TestRenderer.create(<Image {...props} />);
expect(result.toJSON()).toMatchSnapshot();
});

Expand Down
12 changes: 9 additions & 3 deletions packages/components/__tests__/image.node.tests.tsx
Expand Up @@ -4,7 +4,8 @@

import React from "react";
import TestRenderer from "react-test-renderer";
import { Head } from "frontity";
import { HelmetProvider } from "frontity";
import { HelmetContext } from "frontity/types";
import Image from "../image";

describe("Image", () => {
Expand Down Expand Up @@ -33,8 +34,13 @@ describe("Image", () => {
className: "fake-class-name"
};

const image = TestRenderer.create(<Image {...props} />).toJSON();
const head = Head.peek();
const helmetContext: HelmetContext = {};
const image = TestRenderer.create(
<HelmetProvider context={helmetContext}>
<Image {...props} />
</HelmetProvider>
).toJSON();
const head = helmetContext.helmet;

expect(image).toMatchSnapshot();
expect(head.script.toString()).toMatchSnapshot();
Expand Down
2 changes: 1 addition & 1 deletion packages/connect/src/index.d.ts
Expand Up @@ -94,7 +94,7 @@ export function batch<T = any>(
args?: any[]
): T;

export type InitializedStore<St extends Store> = Omit<
export type InitializedStore<St extends Store = Store> = Omit<
St,
"state" | "actions"
> & {
Expand Down
3 changes: 2 additions & 1 deletion packages/core/package.json
Expand Up @@ -68,6 +68,7 @@
"react": "^16.8.3",
"react-dom": "^16.8.3",
"require-from-string": "^2.0.2",
"react-helmet-async": "^1.0.2",
"ts-node": "^8.0.3",
"typescript": "^3.4.5",
"webpack": "^4.29.6",
Expand All @@ -93,7 +94,7 @@
"@types/node": "^11.13.2",
"@types/react": "^16.8.6",
"@types/react-dom": "^16.8.2",
"@types/react-helmet": "^5.0.8",
"@types/react-helmet": "^5.0.9",
"@types/webpack": "^4.4.25",
"@types/webpack-bundle-analyzer": "^2.13.1",
"@types/webpack-dev-middleware": "^2.0.2",
Expand Down
27 changes: 16 additions & 11 deletions packages/core/src/app/index.tsx
Expand Up @@ -3,23 +3,28 @@ import { cache } from "emotion";
import { CacheProvider as EmotionProvider } from "@emotion/core";
import { Provider as ConnectProvider } from "@frontity/connect";
import { Package } from "@frontity/types";
import { HelmetProvider } from "react-helmet-async";
import { HelmetContext } from "../../types";

type Props = {
store: Package;
helmetContext?: HelmetContext;
};

const App: React.FunctionComponent<Props> = ({ store }) => {
const App: React.FunctionComponent<Props> = ({ store, helmetContext = {} }) => {
return (
<EmotionProvider value={cache}>
<ConnectProvider value={store}>
{Object.entries(store.roots).map(([namespace, Root]) => (
<Root key={namespace} />
))}
{Object.entries(store.fills).map(([namespace, Fill]) => (
<Fill key={namespace} />
))}
</ConnectProvider>
</EmotionProvider>
<HelmetProvider context={helmetContext}>
<EmotionProvider value={cache}>
<ConnectProvider value={store}>
{Object.entries(store.roots).map(([namespace, Root]) => (
<Root key={namespace} />
))}
{Object.entries(store.fills).map(([namespace, Fill]) => (
<Fill key={namespace} />
))}
</ConnectProvider>
</EmotionProvider>
</HelmetProvider>
);
};

Expand Down
12 changes: 8 additions & 4 deletions packages/core/src/server/index.tsx
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/ban-ts-ignore, require-atomic-updates */
import Koa from "koa";
import { get } from "koa-route";
import serve from "koa-static";
Expand All @@ -8,7 +9,7 @@ import { renderToString, renderToStaticMarkup } from "react-dom/server";
import { getSettings } from "@frontity/file-settings";
import { ChunkExtractor } from "@loadable/server";
import { extractCritical } from "emotion-server";
import { Helmet } from "react-helmet";
import { HelmetContext } from "@frontity/types";
import getTemplate from "./templates";
import {
getStats,
Expand All @@ -21,7 +22,7 @@ import App from "../app";
import { FrontityTags } from "../../types";
import createStore from "./store";

export default ({ packages }) => {
export default ({ packages }): ReturnType<Koa["callback"]> => {
const app = new Koa();

// Serve static files.
Expand Down Expand Up @@ -83,7 +84,10 @@ export default ({ packages }) => {
})
);

const Component = <App store={store} />;
// Pass a context to HelmetProvider which will hold our state specific to each request.
const helmetContext: HelmetContext = {};

const Component = <App store={store} helmetContext={helmetContext} />;

// If there's no client stats or there is no client entrypoint for the site we
// want to load, we don't extract scripts.
Expand Down Expand Up @@ -137,7 +141,7 @@ export default ({ packages }) => {
)}</script>\n${frontity.script}`;

// Get static head strings.
const head = getHeadTags(Helmet.renderStatic());
const head = getHeadTags(helmetContext.helmet);

// Write the template to body.
ctx.body = template({ html, frontity, head });
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/server/store.ts
@@ -1,4 +1,4 @@
import { createStore } from "@frontity/connect";
import { createStore, InitializedStore } from "@frontity/connect";
import { Package } from "@frontity/types";
import { NormalizedSettings } from "@frontity/file-settings";
import mergePackages from "../utils/merge-packages";
Expand All @@ -14,7 +14,7 @@ export default ({
};
settings: NormalizedSettings;
url: URL;
}) => {
}): InitializedStore => {
const state = initialState({ settings, url });
const merged = mergePackages({ packages, state });
const store = createStore(merged);
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/server/utils/head.ts
@@ -1,4 +1,4 @@
import { HelmetData } from "react-helmet";
import { HelmetData } from "@frontity/types";
import { HeadTags } from "../../../types";

export default (helmet: HelmetData): HeadTags => {
Expand Down
2 changes: 1 addition & 1 deletion packages/frontity/package.json
Expand Up @@ -48,7 +48,7 @@
"node-fetch": "^2.6.0",
"ora": "^3.4.0",
"ramda": "^0.26.1",
"react-helmet": "^5.2.1",
"react-helmet-async": "^1.0.2",
"tar": "^4.4.8",
"ts-node": "^8.0.3",
"typescript": "^3.4.5"
Expand Down
2 changes: 1 addition & 1 deletion packages/frontity/src/index.ts
@@ -1,6 +1,6 @@
export { css, Global, keyframes } from "@emotion/core";
export { default as styled } from "@emotion/styled";
export { Helmet as Head } from "react-helmet";
export { Helmet as Head, HelmetProvider } from "react-helmet-async";
export { default as loadable } from "@loadable/component";
export { observe, batch } from "@frontity/connect";

Expand Down
30 changes: 30 additions & 0 deletions packages/types/src/helmet.ts
@@ -0,0 +1,30 @@
// Helmet types, from "react-helmet".
// We lost access to the types when we switched to react-helmet-async.
interface HelmetDatum {
toString(): string;
toComponent(): React.Component<any>;
}
interface HelmetHTMLBodyDatum {
toString(): string;
toComponent(): React.HTMLAttributes<HTMLBodyElement>;
}
interface HelmetHTMLElementDatum {
toString(): string;
toComponent(): React.HTMLAttributes<HTMLElement>;
}
export interface HelmetData {
base: HelmetDatum;
bodyAttributes: HelmetHTMLBodyDatum;
htmlAttributes: HelmetHTMLElementDatum;
link: HelmetDatum;
meta: HelmetDatum;
noscript: HelmetDatum;
script: HelmetDatum;
style: HelmetDatum;
title: HelmetDatum;
titleAttributes: HelmetDatum;
}

export interface HelmetContext {
helmet?: HelmetData;
}
1 change: 1 addition & 0 deletions packages/types/src/index.ts
Expand Up @@ -4,3 +4,4 @@ export { default as Action } from "./action";
export { default as Derived } from "./derived";
export { default as State } from "./state";
export { default as Connect } from "./connect";
export * from "./helmet";

0 comments on commit 0ea885b

Please sign in to comment.