Skip to content

Conversation

@dancastellon
Copy link
Contributor

@dancastellon dancastellon commented Jul 9, 2018

Resolves #4353
Impact: minor
Type: feature

Issue

Reaction currently has no sitemap.xml - a file that allows search engines visibility into a website's pages. Without it, search engines must manually crawl and find pages through links.

Solution

A sitemap generator plugin that creates and stores XML for a sitemap index, as well as sitemaps for tag pages, PDPs, and arbitrary URLs that can be added via an event hook.

There is a recurring job that runs every 24 hours (can be changed) that generates the sitemaps. There is also a button to manually trigger a refresh, at Dashboard -> Shop -> Options - along with a notification that appears when it's completed.

GraphQL TBD (separate issue)

Breaking changes

None

Testing

  1. Reset the db (translations updated) and use reaction-data-loader to load the dev dataset
  2. Create some products and tags - some archived/non-visible, some visible/published
  3. Login as admin and visit Dashboard -> Shop Settings -> Options
  4. Click "Refresh sitemap"
  5. Confirm you get a notification (bell icon) as well as a Toast alert.
  6. See Sitemaps collection and confirm correct XML by handle: sitemap.xml, sitemap-pages-1.xml, sitemap-tags-1.xml, sitemap-products-1.xml
  7. Visit /sitemap.xml and confirm it loads and displays sitemap index XML
  8. Visit each of the individual sitemap URLs and confirm they load/display valid XML
  9. In the DB, confirm you see a Sitemaps collection with a document for each sitemap.
  10. Confirm you see "BASE_URL" in place of any actual URLs in DB sitemaps
  11. Without updating a tag or product, click the sitemap refresh button again and confirm that the sitemaps for tags and products did not regenerate, but that the sitemap index (sitemap.xml) and the one for pages, has regenerated.
  12. Update a tag's title (I did it by editing the main tag nav), refresh sitemap, and confirm the tag sitemaps did regenerate, but not product sitemaps
  13. Update a product field (such as the title), refresh sitemap, and confirm product sitemaps did regenerate
  14. Run against retailer and miderprise databases - confirm job runs in background (doesn't stop app UI from functioning), and creates the correct number of sitemaps (1k URLs per sitemap max).
  15. At Shop -> Options, change the "Sitemap refresh period" value to something really short, like "every 30 seconds"
  16. Restart the server for the job schedule to update (this appears to be the same as other refresh period settings, like open exchange rates)
  17. Confirm the job runs as scheduled.

@dancastellon dancastellon requested a review from brent-hoover July 9, 2018 22:19
@brent-hoover
Copy link
Collaborator

@dancastellon You've got some lint problems here. Make sure it passes npm run lint

Copy link
Collaborator

@brent-hoover brent-hoover left a comment

Choose a reason for hiding this comment

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

This is looking pretty good. Couple of questions and that's all.

import { Meteor } from "meteor/meteor";
import { check, Match } from "meteor/check";
import Hooks from "@reactioncommerce/hooks";
import Reaction from "/imports/plugins/core/core/server/Reaction";
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should be imported from /server/api

Copy link
Contributor Author

@dancastellon dancastellon Jul 11, 2018

Choose a reason for hiding this comment

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

@zenweasel Release 1.14 changes that. It looks like all references to /server/api have been moved to /imports/plugins/core/core/server/Reaction.

Copy link
Contributor

Choose a reason for hiding this comment

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

as @dancastellon mentioned, there is no more /server/api in release 1.14

<lastmod>LAST_MOD</lastmod>
<changefreq>daily</changefreq>
<priority>0.8</priority>
</url>`.replace("URL", url);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Are we replacing LAST_MOD somewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@zenweasel Yes, see getSitemapXML below.

* @param {Array} [shopIds] - _id of shops to generate sitemaps for. Defaults to primary shop _id
* @param {Number} [urlsPerSitemap] - Max # of URLs per sitemap
*/
export default function generateSitemaps (shopIds = [], urlsPerSitemap = DEFAULT_URLS_PER_SITEMAP) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

These methods could definitely use some tests

@dancastellon dancastellon force-pushed the feat-4353-dancastellon-sitemap-generator branch from 3afad21 to db2d035 Compare July 10, 2018 15:47
@dancastellon dancastellon changed the title WIP: Feat 4353 dancastellon sitemap generator [WIP]: #4353 Plugin for auto-generated sitemaps Jul 11, 2018
@dancastellon
Copy link
Contributor Author

@zenweasel, @spencern This is ready for a review, but let's not merge yet - I need to test against the miderprise dataset, which Grigg will be setting up on a hosted DB, likely next week.

@dancastellon dancastellon requested a review from spencern July 13, 2018 15:27
@spencern spencern removed their request for review July 13, 2018 16:42
@dancastellon dancastellon changed the title [WIP]: #4353 Plugin for auto-generated sitemaps #4353 Plugin for auto-generated sitemaps Jul 17, 2018
@dancastellon
Copy link
Contributor Author

@zenweasel Today I was able to test the sitemap generator with the miderprise dataset. It took roughly 3.5 minutes, but the app was useable while it was generating. I believe this one's ready for review.

Copy link
Collaborator

@brent-hoover brent-hoover left a comment

Choose a reason for hiding this comment

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

Just some style things to take care of. Have not tested yet.

type: String,
label: "Open Exchange Rates App Id"
label: "Open Exchange Rates App Id",
optional: true
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you explain why you needed to make this change since it doesn't appear related to this PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@zenweasel Without making this field optional I'm unable to save the shop options form, unless I add an App ID for Open Exchange Rates. Shop options is where I added the sitemap refresh setting & regenerate button. I just noticed that on a fresh install, I also had to make settings.cart in the same schema optional. Does it make sense to have the sitemap settings be in a separate form? Or perhaps somewhere else, like the Shop -> General form?

@@ -0,0 +1,32 @@
import { Meteor } from "meteor/meteor";
import React, { Component } from "react";
Copy link
Collaborator

Choose a reason for hiding this comment

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

React import should always go before Meteor import: https://docs.reactioncommerce.com/docs/styleguide#syntax-and-style-conventions

@@ -0,0 +1,29 @@
import Random from "@reactioncommerce/random";
Copy link
Collaborator

Choose a reason for hiding this comment

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

Filename should use hyphens rather than camel-casing

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks @zenweasel - updated all filenames to be hyphenated

@@ -0,0 +1,23 @@
import { Meteor } from "meteor/meteor";
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this a pattern you see elsewhere as I am not a big fan of putting much besides imports into index.js

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@zenweasel I updated this to follow the core plugin's pattern for defining methods. Method itself in a separate file, that is simply imported in methods/index.js and exported.

@brent-hoover
Copy link
Collaborator

@dancastellon Also, you still have lint errors

@brent-hoover
Copy link
Collaborator

brent-hoover commented Jul 17, 2018

@dancastellon Following up on the notes from the call, if I click on "Refresh Sitemaps Now" I don't see any visual feedback that anything has started, much less completed in either the server console or the UI. I should get at least some sort of "started regenerating sitemap" message or something.

@brent-hoover
Copy link
Collaborator

Shouldn't I be seeing these value substituted in the actual XML?

2018-07-18_06-32-30

@dancastellon
Copy link
Contributor Author

Thanks @rymorgan, I've made the changes you suggested, see below:

updated-sitemap-buttons

updated-notification

@dancastellon
Copy link
Contributor Author

@rymorgan Also, the notification. Let me know if I should change the text:

notification

@rymorgan
Copy link
Contributor

@dancastellon I think the notification should say 'Sitemap refresh is complete' to match the language in the toast

Other than that it LGTM. The toast alert was coming up for me but could very well be something wrong with my local reaction instance so as long as @zenweasel can confirm that is working then I'm good with this.

@dancastellon
Copy link
Contributor Author

@rymorgan Done, thanks. I have seen times previously where the toast doesn't show up sometimes. @zenweasel Let me know if you still don't see the toast. Might be a core bug.

@brent-hoover
Copy link
Collaborator

brent-hoover commented Jul 27, 2018

If I put in an invalid interval I don't get any validation but it throws this error in the server console:
No valid available later.js times in schedule after Fri Jul 27 2018 13:55:06 GMT+0800 (+08)

I don't know that we do a good job validating any of those values in that screen. Maybe it might make sense to just do a dropdown there? Every 24 hours/Every 12 hours/Every 1 hour? Or maybe the later library gives you some way of validating it.

@brent-hoover
Copy link
Collaborator

brent-hoover commented Jul 27, 2018

When I click on "Refresh sitemap" I get the translation key instead of the message.

@brent-hoover
Copy link
Collaborator

brent-hoover commented Jul 27, 2018

This is a nitpick probably but: If I click on "View All" for notifications, each of the notifications is a link but that link just takes you to the home page. Maybe it should take you to the XML file instead?

@brent-hoover
Copy link
Collaborator

@dancastellon Found a few little things to fix but it's getting pretty close

@brent-hoover brent-hoover dismissed their stale review July 27, 2018 06:39

Issues addressed

Copy link
Collaborator

@brent-hoover brent-hoover left a comment

Choose a reason for hiding this comment

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

A few issues left to address

@dancastellon
Copy link
Contributor Author

@zenweasel I've made the changes you suggested. Tagging @rymorgan as I've switched out some form fields with their new Reaction Components counterparts

  1. Used a select box to let the admin choose from 3 options - every 24 hours, 12 hours, 1 hour
  2. Linked the notification to sitemap.xml
  3. Added default values to translations so that Toast alert never shows the i18nkey

sitemap-settings-new-components

@rymorgan
Copy link
Contributor

rymorgan commented Jul 27, 2018

@dancastellon Is this still under shops/options? I'm not seeing it anymore on your branch (might be user error ?).

From your screenshot though I think this approach is good. And every place where we convert to components in our component library is a win. 👍

@dancastellon
Copy link
Contributor Author

dancastellon commented Jul 30, 2018

@rymorgan Yes, it's still under Shop -> Options. I did rename the React component behind the sitemap settings, so maybe try a hard refresh? Are you seeing any browser console errors?

@rymorgan
Copy link
Contributor

Ok, I got it working. From a UI/UX perspective, it looks good to me 👍

Copy link
Collaborator

@brent-hoover brent-hoover left a comment

Choose a reason for hiding this comment

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

Looks good. 👍

@aldeed aldeed changed the base branch from release-1.14.0 to release-1.15.0 August 2, 2018 03:12
@aldeed aldeed merged commit c8d2400 into release-1.15.0 Aug 16, 2018
@aldeed aldeed deleted the feat-4353-dancastellon-sitemap-generator branch August 16, 2018 23:02
@spencern spencern mentioned this pull request Aug 22, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants