Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSR: Use document-head to populate title, metas, and links; drop Helmet #7600

Merged
merged 27 commits into from
Oct 3, 2016

Conversation

ockham
Copy link
Contributor

@ockham ockham commented Aug 22, 2016

This PR:

  • has the theme sheet and showcase use DocumentHead instead of Head (which was a rather specialized component tailored to the theme showcase's SEO needs, based on `react-helmet``
  • drops Head, and the react-helmet dependency
  • modifies server/render to use data from the document-head state to populate SEO relevant fields (title, meta, link) for SSR
  • removes description related reducer and actions.
    • Description meta can be handled by just using addMeta, so I don't think it's worthwhile having specialized functions around.

To test:

  • While logged out, check a given theme sheet's page source. Verify that SEO relevant tags are present (title, meta, link). (Compare with master or production.)
  • While logged out, navigate to the showcase (http://calypso.localhost:3000/design), and click on any theme. Watch the title change -- at no point should it not make any sense.
  • Same when logged in. (Also, there obviously shouldn't be any errors, console or otherwise.)

TODO (separate PR):

  • Make sure we SSR title et al for /design (this isn't currently done on master, so not a regression)

Fixes #3795

Test live: https://calypso.live/?branch=remove/head

@@ -348,46 +348,58 @@ const ThemeSheet = React.createClass( {
const analyticsPageTitle = `Themes > Details Sheet${ section ? ' > ' + titlecase( section ) : '' }${ siteID ? ' > Site' : '' }`;

const { name: themeName, description } = this.props;
const title = i18n.translate( '%(themeName)s Theme', {
const title = themeName && i18n.translate( '%(themeName)s Theme', {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was the reason for the themeName && change? This won't prevent the <DocumentHead /> from dispatching the title, will it?

Per:

if ( 'title' in this.props ) {
this.props.setTitle( title );
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was the reason for the themeName && change?

Basically to retain logic that was previously here.

@aduth
Copy link
Contributor

aduth commented Aug 25, 2016

Looking forward to this 🎉

@ockham ockham force-pushed the remove/head branch 5 times, most recently from 9407ab7 to 8bccbf2 Compare September 27, 2016 00:40
@ockham ockham added [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. and removed [Status] In Progress labels Sep 27, 2016
@ockham ockham force-pushed the remove/head branch 2 times, most recently from 033a4b0 to 0a7221d Compare September 28, 2016 13:57
return (
<Main className="themes">
<DocumentHead title={ themesMeta[ tier ].title } metas={ metas } />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prop for metas is meta, not metas.

* @param {Object} state Global state tree
* @return {Object[]} Array of meta objects
*/
export function getMeta( state ) {
Copy link
Contributor

@aduth aduth Sep 28, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, in the context of global selectors, should they come to reality, would getMeta be sufficiently unique? Seems less so than getTitle, though a similar argument could be made there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I'll rename them to be in line with the setters (i.e. actions).

const title = getFormattedTitle( context.store.getState() );
const metas = getMeta( context.store.getState() );
const links = getLink( context.store.getState() );
context.head = { title, metas, links };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We wrap this in context.store condition, but the Jade template assumes head.title will always exist. Do we need to be safer there too? Or remove the context.store check?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't just remove the context.store check or context.store.getState() might fail. Fixing this with f7ffb39 by falling back to undefined attrs.

@aduth aduth added [Status] Needs Author Reply and removed [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. labels Sep 28, 2016
@ockham ockham added [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. and removed [Status] Needs Author Reply labels Sep 28, 2016
@ockham
Copy link
Contributor Author

ockham commented Sep 28, 2016

Okay, addressed feedback, including renaming of all selectors. Some have pretty long names now...

@@ -19,7 +21,7 @@ const UNREAD_COUNT_CAP = 40;
* @param {Object} state Global state tree
* @return {?String} Document title
*/
export function getTitle( state ) {
export function getDocumentHeadTitle( state ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

client/reader/full-post/controller.js still imports as getTitle in this branch.

context.initialReduxState = pick( context.store.getState(), 'documentHead', 'ui', 'themes' );
}

context.head = { title, metas, links };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do the defaults and context.head assignment need to be outside of the config / context.user condition block too to ensure it's always set?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. This might've gone unnoticed in testing since the feature flag is on in all environments, and context.user is notoriously unset on the server in development.

@aduth aduth added [Status] Needs Author Reply and removed [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. labels Sep 29, 2016
ockham added 22 commits October 3, 2016 19:36
Description meta can be handled by just using addMeta, so I don't think it's worthwhile having specialized functions around.
@ockham ockham merged commit cb45a9a into master Oct 3, 2016
@ockham ockham deleted the remove/head branch October 3, 2016 19:35
@matticbot matticbot removed the [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. label Oct 3, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature Group] Appearance & Themes Features related to the appearance of sites. Server Side Rendering
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants