Skip to content

Commit 7b9f6fe

Browse files
authored
Include canonical <link> for user review pages (#13127)
* Include canonical <link> for user review pages Also add rel=nofollow to links to it filtering user reviews by score as it's useless for search engines to visit, it's the same content but filtered.
1 parent c5c7383 commit 7b9f6fe

File tree

4 files changed

+56
-0
lines changed

4 files changed

+56
-0
lines changed

src/amo/components/RatingsByStar/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ export class RatingsByStarBase extends React.Component<InternalProps> {
151151
<Link
152152
className="RatingsByStar-row"
153153
key={star}
154+
rel="nofollow"
154155
title={getLinkTitles(star, starCount) || ''}
155156
to={reviewListURL({
156157
addonSlug: addon.slug,

src/amo/pages/AddonReviewList/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { DEFAULT_API_PAGE_SIZE } from 'amo/api';
1111
import AddonReviewCard from 'amo/components/AddonReviewCard';
1212
import AddonSummaryCard from 'amo/components/AddonSummaryCard';
1313
import FeaturedAddonReview from 'amo/components/FeaturedAddonReview';
14+
import HeadLinks from 'amo/components/HeadLinks';
1415
import Page from 'amo/components/Page';
1516
import { fetchReviewPermissions, fetchReviews } from 'amo/actions/reviews';
1617
import { setViewContext } from 'amo/actions/viewContext';
@@ -332,6 +333,7 @@ export class AddonReviewListBase extends React.Component<InternalProps> {
332333
{reviewId && <meta name="robots" content="noindex, follow" />}
333334
</Helmet>
334335
)}
336+
{addon && !reviewId && <HeadLinks />}
335337

336338
{errorHandler.renderErrorIfPresent()}
337339

tests/unit/amo/components/TestRatingsByStar.js

+1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ describe(__filename, () => {
7878
'href',
7979
`/en-US/android${reviewListURL({ addonSlug: addon.slug, score })}`,
8080
);
81+
expect(link).toHaveAttribute('rel', 'nofollow');
8182
expect(within(link).getByText(count)).toBeInTheDocument();
8283
}
8384

tests/unit/amo/pages/TestAddonReviewList.js

+52
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import config from 'config';
12
import { waitFor } from '@testing-library/react';
23
import userEvent from '@testing-library/user-event';
34

@@ -17,6 +18,7 @@ import {
1718
CLIENT_APP_FIREFOX,
1819
SET_VIEW_CONTEXT,
1920
} from 'amo/constants';
21+
import { hrefLangs } from 'amo/languages';
2022
import { fetchAddon, loadAddon } from 'amo/reducers/addons';
2123
import {
2224
changeLocation,
@@ -700,6 +702,56 @@ describe(__filename, () => {
700702
expect(getElements('meta[name="robots"]')).toHaveLength(0);
701703
});
702704

705+
it('renders a canonical link for the list page with alternates', async () => {
706+
renderWithAddonAndReviews();
707+
708+
const getExpectedURL = (locale, app) => {
709+
return `${config.get(
710+
'baseURL',
711+
)}/${locale}/${app}/addon/${defaultSlug}/reviews/`;
712+
};
713+
714+
await waitFor(() =>
715+
expect(getElement('link[rel="canonical"]')).toHaveAttribute(
716+
'href',
717+
getExpectedURL('en-US', 'firefox'),
718+
),
719+
);
720+
721+
await waitFor(() =>
722+
expect(getElement('link[rel="alternate"]')).toBeInTheDocument(),
723+
);
724+
725+
expect(getElements('link[rel="alternate"]')).toHaveLength(
726+
hrefLangs.length,
727+
);
728+
729+
const hrefLangsMap = config.get('hrefLangsMap');
730+
hrefLangs.forEach((hrefLang) => {
731+
const locale = hrefLangsMap[hrefLang] || hrefLang;
732+
expect(
733+
getElement(`link[rel="alternate"][hreflang="${hrefLang}"]`),
734+
).toHaveAttribute('href', getExpectedURL(locale, 'firefox'));
735+
});
736+
});
737+
738+
it('renders a canonical with no query string', async () => {
739+
renderWithAddonAndReviews({ score: 5 });
740+
741+
const getExpectedURL = (locale, app) => {
742+
return `${config.get(
743+
'baseURL',
744+
)}/${locale}/${app}/addon/${defaultSlug}/reviews/`;
745+
};
746+
747+
await waitFor(() =>
748+
expect(getElement('link[rel="canonical"]')).toHaveAttribute(
749+
'href',
750+
getExpectedURL('en-US', 'firefox'),
751+
),
752+
);
753+
});
754+
703755
it('renders a robots meta tag when there is a featured review', async () => {
704756
const reviews = [
705757
{ ...fakeReview, id: 1, score: 1 },

0 commit comments

Comments
 (0)