mirror of
https://github.com/kingomarnajjar/flex-template-web.git
synced 2026-07-28 12:43:11 +10:00
Merge pull request #476 from sharetribe/canonical-listing-url
Canonical listing page URL without slug
This commit is contained in:
commit
12ded4c18d
6 changed files with 51 additions and 8 deletions
|
|
@ -37,6 +37,7 @@ describe('Application', () => {
|
|||
'/': 'Book saunas everywhere | Saunatime',
|
||||
'/s': 'Search results for map search | Saunatime',
|
||||
'/l/listing-title-slug/1234': 'Loading listing…',
|
||||
'/l/1234': 'Loading listing…',
|
||||
'/u/1234': 'Profile page with display name: 1234',
|
||||
'/login': 'Login',
|
||||
'/signup': 'Sign up',
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ class PageComponent extends Component {
|
|||
title,
|
||||
twitterHandle,
|
||||
twitterImages,
|
||||
canonicalPath,
|
||||
updated,
|
||||
} = this.props;
|
||||
|
||||
|
|
@ -86,10 +87,20 @@ class PageComponent extends Component {
|
|||
const metaTitle = title || schemaTitle;
|
||||
const metaDescription = description || schemaDescription;
|
||||
const facebookImgs = facebookImages || [
|
||||
{ name: 'facebook', url: `${config.canonicalRootURL}${facebookImage}`, width: 1200, height: 630 },
|
||||
{
|
||||
name: 'facebook',
|
||||
url: `${config.canonicalRootURL}${facebookImage}`,
|
||||
width: 1200,
|
||||
height: 630,
|
||||
},
|
||||
];
|
||||
const twitterImgs = twitterImages || [
|
||||
{ name: 'twitter', url: `${config.canonicalRootURL}${twitterImage}`, width: 600, height: 314 },
|
||||
{
|
||||
name: 'twitter',
|
||||
url: `${config.canonicalRootURL}${twitterImage}`,
|
||||
width: 600,
|
||||
height: 314,
|
||||
},
|
||||
];
|
||||
|
||||
const metaToHead = metaTagProps({
|
||||
|
|
@ -129,7 +140,7 @@ class PageComponent extends Component {
|
|||
}}
|
||||
>
|
||||
<title>{title}</title>
|
||||
<link rel="canonical" href={canonicalURL(pathWithSearch)} />
|
||||
<link rel="canonical" href={canonicalURL(canonicalPath || pathWithSearch)} />
|
||||
<meta httpEquiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta httpEquiv="Content-Language" content={intl.locale} />
|
||||
{metaTags}
|
||||
|
|
@ -170,6 +181,7 @@ PageComponent.defaultProps = {
|
|||
description: null,
|
||||
facebookImages: null,
|
||||
twitterImages: null,
|
||||
canonicalPath: null,
|
||||
published: null,
|
||||
schema: null,
|
||||
tags: null,
|
||||
|
|
@ -209,6 +221,7 @@ PageComponent.propTypes = {
|
|||
title: string.isRequired, // page title
|
||||
twitterHandle: string, // twitter handle
|
||||
updated: string, // article:modified_time
|
||||
canonicalPath: string, // link rel=canonical
|
||||
|
||||
// from withRouter
|
||||
history: shape({
|
||||
|
|
|
|||
|
|
@ -115,7 +115,8 @@ export class ListingPageComponent extends Component {
|
|||
|
||||
handleSubmit(values) {
|
||||
const { flattenedRoutes, history, getListing, params, useInitialValues } = this.props;
|
||||
const listing = getListing(new UUID(params.id));
|
||||
const listingId = new UUID(params.id);
|
||||
const listing = getListing(listingId);
|
||||
|
||||
this.setState({ isBookingModalOpenOnMobile: false });
|
||||
|
||||
|
|
@ -166,8 +167,11 @@ export class ListingPageComponent extends Component {
|
|||
sendVerificationEmailInProgress,
|
||||
sendVerificationEmailError,
|
||||
onResendVerificationEmail,
|
||||
flattenedRoutes,
|
||||
} = this.props;
|
||||
const currentListing = ensureListing(getListing(new UUID(params.id)));
|
||||
const listingId = new UUID(params.id);
|
||||
const currentListing = ensureListing(getListing(listingId));
|
||||
const listingSlug = params.slug || createSlug(currentListing.attributes.title || '');
|
||||
const {
|
||||
address = '',
|
||||
description = '',
|
||||
|
|
@ -299,7 +303,7 @@ export class ListingPageComponent extends Component {
|
|||
}
|
||||
};
|
||||
|
||||
const editParams = { ...params, type: 'edit', tab: 'description' };
|
||||
const editParams = { id: listingId.uuid, slug: listingSlug, type: 'edit', tab: 'description' };
|
||||
|
||||
const listingClasses = classNames(css.pageRoot);
|
||||
|
||||
|
|
@ -341,6 +345,10 @@ export class ListingPageComponent extends Component {
|
|||
{ title, price: formattedPrice, siteTitle }
|
||||
);
|
||||
|
||||
const canonicalPath = createResourceLocatorString('ListingPageCanonical', flattenedRoutes, {
|
||||
id: listingId.uuid,
|
||||
});
|
||||
|
||||
return (
|
||||
<Page
|
||||
authInfoError={authInfoError}
|
||||
|
|
@ -352,6 +360,7 @@ export class ListingPageComponent extends Component {
|
|||
description={description}
|
||||
facebookImages={facebookImages}
|
||||
twitterImages={twitterImages}
|
||||
canonicalPath={canonicalPath}
|
||||
schema={
|
||||
`
|
||||
{
|
||||
|
|
@ -513,7 +522,7 @@ ListingPageComponent.propTypes = {
|
|||
intl: intlShape.isRequired,
|
||||
params: shape({
|
||||
id: string.isRequired,
|
||||
slug: string.isRequired,
|
||||
slug: string,
|
||||
}).isRequired,
|
||||
authInfoError: instanceOf(Error),
|
||||
authInProgress: bool.isRequired,
|
||||
|
|
|
|||
|
|
@ -17,7 +17,16 @@ describe('ListingPage', () => {
|
|||
const listing1 = createListing('listing1', {}, { author: createUser('user-1') });
|
||||
const getListing = () => listing1;
|
||||
const props = {
|
||||
flattenedRoutes: [],
|
||||
flattenedRoutes: [
|
||||
// Fake route since a circular dependency prevents using the
|
||||
// full routesConfiguration here
|
||||
{
|
||||
path: '/l/:id',
|
||||
exact: true,
|
||||
name: 'ListingPageCanonical',
|
||||
component: noop,
|
||||
},
|
||||
],
|
||||
location: { search: '' },
|
||||
history: {
|
||||
push: () => console.log('HistoryPush called'),
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ exports[`ListingPage matches snapshot 1`] = `
|
|||
<Page
|
||||
authInfoError={null}
|
||||
author="user-1 display name"
|
||||
canonicalPath="/l/listing1"
|
||||
contentType="website"
|
||||
description="listing1 description"
|
||||
facebookImages={Array []}
|
||||
|
|
|
|||
|
|
@ -112,6 +112,16 @@ const routesConfiguration = [
|
|||
component: props => <EditListingPage {...props} />,
|
||||
loadData: (params, search) => EditListingPage.loadData(params, search),
|
||||
},
|
||||
|
||||
// Canonical path should be after the `/l/new` path since they
|
||||
// conflict and `new` is not a valid listing UUID.
|
||||
{
|
||||
path: '/l/:id',
|
||||
exact: true,
|
||||
name: 'ListingPageCanonical',
|
||||
loadData: (params, search) => ListingPage.loadData(params, search),
|
||||
component: props => <ListingPage {...props} tab="listing" />,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue