Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions src/Apps/Artist/ArtistApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { useScrollToOpenArtistAuthModal } from "Utils/Hooks/useScrollToOpenArtis
import type { ArtistApp_artist$data } from "__generated__/ArtistApp_artist.graphql"
import { createFragmentContainer, graphql } from "react-relay"
import { ArtistHeaderFragmentContainer } from "./Components/ArtistHeader/ArtistHeader"
import { ArtistMetaFragmentContainer } from "./Components/ArtistMeta/ArtistMeta"

interface ArtistAppProps {
artist: ArtistApp_artist$data
Expand All @@ -20,8 +19,6 @@ const ArtistApp: React.FC<React.PropsWithChildren<ArtistAppProps>> = ({

return (
<>
<ArtistMetaFragmentContainer artist={artist} />

<Analytics contextPageOwnerId={artist.internalID}>
<Spacer y={[0, 4]} />

Expand Down Expand Up @@ -54,7 +51,6 @@ const ArtistApp: React.FC<React.PropsWithChildren<ArtistAppProps>> = ({
export const ArtistAppFragmentContainer = createFragmentContainer(ArtistApp, {
artist: graphql`
fragment ArtistApp_artist on Artist {
...ArtistMeta_artist
...ArtistHeader_artist
internalID
slug
Expand Down
33 changes: 21 additions & 12 deletions src/Apps/Artist/Components/ArtistMeta/ArtistMeta.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,42 @@
import { MetaTags } from "Components/MetaTags"
import { ArtistStructuredData } from "Components/Seo/ArtistStructuredData"
import { MetaTags } from "Components/MetaTags"
import { PaginatedMetaTags } from "Components/PaginatedMetaTags"
import { getENV } from "Utils/getENV"
import type { ArtistMeta_artist$data } from "__generated__/ArtistMeta_artist.graphql"
import { Meta } from "react-head"
import { createFragmentContainer, graphql } from "react-relay"
import { useCanonicalHref } from "./useCanonicalHref"

interface Props {
artist: ArtistMeta_artist$data
title?: string | null
description?: string | null
isPaginated?: boolean
}

export const ArtistMeta: React.FC<React.PropsWithChildren<Props>> = ({
artist,
title,
description,
isPaginated = false,
}) => {
const alternateNames = artist?.alternateNames || []

const pathname = useCanonicalHref({
isInSeoExperiment: !!artist.isInSeoExperiment,
href: artist.href ?? "/",
})
const finalTitle = title || artist.meta?.title
const finalDescription = description || artist.meta?.description
const imageURL = artist.coverArtwork?.image?.large

return (
<>
<MetaTags
title={artist.meta.title}
description={artist.meta.description}
imageURL={artist.coverArtwork?.image?.large}
pathname={pathname}
/>
{isPaginated ? (
<PaginatedMetaTags title={finalTitle} description={finalDescription} />
) : (
<MetaTags
title={finalTitle}
description={finalDescription}
imageURL={imageURL}
pathname={artist.href}
/>
)}

<Meta
property="og:url"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,76 +40,18 @@ const getMetaBy = (selectors): Element | null => {
}

describe("AdminMeta", () => {
describe("canonical link", () => {
it("renders", () => {
renderWithRelay({
Artist: () => ({
href: "/artist/example-artist",
}),
})

const linkTag = document.querySelector("link[rel='canonical']")
expect(linkTag?.getAttribute("href")).toEqual("/artist/example-artist")
})
})

describe("without an artist description", () => {
it("renders the default description", () => {
describe("OpenGraph tags", () => {
it("renders artist OpenGraph tags", () => {
renderWithRelay({
Artist: () => ({
slug: "example-artist",
href: "/artist/example-artist",
meta: { description: null, title: "Example Artist" },
}),
})

const defaultDescription =
"Artsy is the world’s largest online art marketplace. Browse over 1 million artworks by iconic and emerging artists from 4000+ galleries and top auction houses."

expect(
getMetaBy({ name: "description" })?.getAttribute("content"),
).toEqual(defaultDescription)

expect(
getMetaBy({ property: "og:description" })?.getAttribute("content"),
).toEqual(defaultDescription)

expect(
getMetaBy({ property: "twitter:description" })?.getAttribute("content"),
).toEqual(defaultDescription)
})
})

describe("with an artist that has a description", () => {
it("renders meta tags with that description", () => {
const artist = {
href: "/artist/example-artist",
meta: {
description: "Very important painter!",
title: "Example Artist",
},
}
renderWithRelay({ Artist: () => artist })

expect(
getMetaBy({
name: "description",
content: artist.meta.description,
}),
).not.toBeNull()

expect(
getMetaBy({
property: "og:description",
content: artist.meta.description,
}),
).not.toBeNull()

expect(
getMetaBy({
property: "twitter:description",
content: artist.meta.description,
}),
).not.toBeNull()
expect(getMetaBy({ property: "og:url" })).not.toBeNull()
expect(getMetaBy({ property: "og:type" })).not.toBeNull()
})
})

Expand Down
25 changes: 16 additions & 9 deletions src/Apps/Artist/Routes/AuctionResults/ArtistAuctionResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
Text,
} from "@artsy/palette"
import { initialAuctionResultsFilterState } from "Apps/Artist/Routes/AuctionResults/initialAuctionResultsFilterState"
import { ArtistMetaFragmentContainer } from "Apps/Artist/Components/ArtistMeta/ArtistMeta"
import { allowedAuctionResultFilters } from "Apps/Artist/Utils/allowedAuctionResultFilters"
import { paramsToCamelCase } from "Components/ArtworkFilter/Utils/paramsCasing"
import { updateUrl } from "Components/ArtworkFilter/Utils/urlBuilder"
Expand All @@ -30,7 +31,6 @@ import type { ArtistAuctionResults_artist$data } from "__generated__/ArtistAucti
import { isEqual } from "lodash"
import type * as React from "react"
import { useContext, useState } from "react"
import { Meta, Title } from "react-head"
import {
type RelayRefetchProp,
createRefetchContainer,
Expand Down Expand Up @@ -222,14 +222,17 @@ const AuctionResultsContainer: React.FC<
)
}

const { title, description } = artist.meta
const { title, description } = artist.auctionResultsMeta

if (!artist.statuses?.auctionLots) {
return (
<>
<Title>{title}</Title>
<Meta name="title" content={title} />
<Meta name="description" content={description} />
<ArtistMetaFragmentContainer
artist={artist}
title={title}
description={description}
isPaginated={true}
/>

<Spacer y={[2, 0]} />

Expand All @@ -240,9 +243,12 @@ const AuctionResultsContainer: React.FC<

return (
<>
<Title>{title}</Title>
<Meta name="title" content={title} />
<Meta name="description" content={description} />
<ArtistMetaFragmentContainer
artist={artist}
title={title}
description={description}
isPaginated={true}
/>

<Jump id="marketSignalsTop" />

Expand Down Expand Up @@ -428,10 +434,11 @@ export const ArtistAuctionResultsRefetchContainer = createRefetchContainer(
allowEmptyCreatedDates: { type: "Boolean" }
state: { type: "AuctionResultsState", defaultValue: ALL }
) {
...ArtistMeta_artist
slug
internalID
name
meta(page: AUCTION_RESULTS) {
auctionResultsMeta: meta(page: AUCTION_RESULTS) {
description
title
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -488,11 +488,44 @@ const AuctionResultsFixture: ArtistAuctionResults_Test_Query$rawResponse = {
id: "QXJ0aXN0OnBhYmxvLXBpY2Fzc28=",
slug: "pablo-picasso",
name: "Pablo Picasso",
nationality: "Spanish",
birthday: "October 25, 1881",
deathday: "April 8, 1973",
alternateNames: [
"Pablo Diego José Francisco de Paula Juan Nepomuceno María de los Remedios Cipriano de la Santísima Trinidad Ruiz y Picasso",
],
href: "/artist/pablo-picasso",
isInSeoExperiment: false,
gender: "male",
meta: {
description:
"Find out about Pablo Picassos auction history, past sales, and current market value. Browse Artsys Price Database for recent auction results from the artist.`",
"Find out about Pablo Picasso's auction history, past sales, and current market value. Browse Artsy's Price Database for recent auction results from the artist.`",
title: "Pablo Picasso - Auction Results and Sales Data | Artsy",
},
auctionResultsMeta: {
description:
"Find out about Pablo Picasso's auction history, past sales, and current market value. Browse Artsy's Price Database for recent auction results from the artist.`",
title: "Pablo Picasso - Auction Results and Sales Data | Artsy",
},
coverArtwork: {
id: "QXJ0d29yazo1ZTJkNWU0NGU1YzNkNjMxYWI2OTYzMDk=", // pragma: allowlist secret
image: {
url: "https://d32dm0rphc51dk.cloudfront.net/Vxf2MR1HwxqDwNovE9O4rg/large.jpg",
large:
"https://d32dm0rphc51dk.cloudfront.net/Vxf2MR1HwxqDwNovE9O4rg/large.jpg",
},
},
partnersConnection: {
edges: [
{
id: "UGFydG5lckFydGlzdEVkZ2U6NWIyZGE5YWE4YjNiODE1N2MzZjdkZDZh", // pragma: allowlist secret
node: {
id: "UGFydG5lcjo1YjJkYTlhYThiM2I4MTU3YzNmN2RkNmE=", // pragma: allowlist secret
href: "/gagosian-gallery",
},
},
],
},
statuses: {
auctionLots: true,
},
Expand Down
13 changes: 4 additions & 9 deletions src/Apps/Artist/Routes/Overview/ArtistOverviewRoute.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Join, Spacer } from "@artsy/palette"
import { ArtistEditorialNewsGridQueryRenderer } from "Apps/Artist/Routes/Overview/Components/ArtistEditorialNewsGrid"
import { ArtistMetaFragmentContainer } from "Apps/Artist/Components/ArtistMeta/ArtistMeta"
import { ArtistOverviewEmpty } from "Apps/Artist/Routes/Overview/Components/ArtistOverviewEmpty"
import { ArtistRelatedGeneCategoriesQueryRenderer } from "Apps/Artist/Routes/Overview/Components/ArtistRelatedGeneCategories"
import { ArtistSeriesRailQueryRenderer } from "Components/ArtistSeriesRail/ArtistSeriesRail"
import type { ArtistOverviewRoute_artist$data } from "__generated__/ArtistOverviewRoute_artist.graphql"
import type * as React from "react"
import { Meta, Title } from "react-head"
import { createFragmentContainer, graphql } from "react-relay"
import { ArtistCareerHighlightsQueryRenderer } from "./Components/ArtistCareerHighlights"
import { ArtistCurrentShowsRailQueryRenderer } from "./Components/ArtistCurrentShowsRail"
Expand All @@ -18,8 +18,6 @@ interface ArtistOverviewRouteProps {
const ArtistOverviewRoute: React.FC<
React.PropsWithChildren<ArtistOverviewRouteProps>
> = ({ artist }) => {
const { title, description } = artist.meta

const hasCareerHighlights = artist.insights.length > 0
const hasArtistSeries = artist.artistSeriesConnection?.totalCount ?? 0 > 0
const hasEditorial = artist.counts?.articles ?? 0 > 0
Expand All @@ -37,9 +35,7 @@ const ArtistOverviewRoute: React.FC<
) {
return (
<>
<Title>{title}</Title>
<Meta name="title" content={title} />
<Meta name="description" content={description} />
<ArtistMetaFragmentContainer artist={artist} />

<Spacer y={[2, 0]} />

Expand All @@ -50,9 +46,7 @@ const ArtistOverviewRoute: React.FC<

return (
<>
<Title>{title}</Title>
<Meta name="title" content={title} />
<Meta name="description" content={description} />
<ArtistMetaFragmentContainer artist={artist} />

<Spacer y={[2, 0]} />

Expand Down Expand Up @@ -93,6 +87,7 @@ export const ArtistOverviewRouteFragmentContainer = createFragmentContainer(
{
artist: graphql`
fragment ArtistOverviewRoute_artist on Artist {
...ArtistMeta_artist
internalID
name
meta(page: ABOUT) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ describe("ArtistOverviewRoute", () => {
Artist: () => ({
name: "artistName",
slug: "artistSlug",
nationality: "American",
birthday: "1990-01-01",
deathday: null,
alternateNames: ["Alt Name"],
href: "/artist/artistslug",
isInSeoExperiment: false,
meta: { title: "Artist Name", description: "Artist description" },
coverArtwork: {
image: { large: "https://example.com/image.jpg" },
},
filterArtworksConnection: {
edges: [
{
Expand All @@ -72,6 +82,8 @@ describe("ArtistOverviewRoute", () => {
artistSeriesConnection: { totalCount: 1 },
articlesConnection: { totalCount: 1 },
showsConnection: { totalCount: 1 },
counts: { artworks: "100", relatedArtists: 5, articles: 3 },
related: { genes: { edges: [{ node: { __typename: "Gene" } }] } },
}),
})

Expand All @@ -88,12 +100,19 @@ describe("ArtistOverviewRoute", () => {
Artist: () => ({
name: "artistName",
slug: "artistSlug",
nationality: null,
birthday: null,
deathday: null,
alternateNames: [],
href: "/artist/artistslug",
isInSeoExperiment: false,
meta: { title: "title", description: "description" },
coverArtwork: null,
filterArtworksConnection: { edges: [] },
insights: [],
artistSeriesConnection: { totalCount: 0 },
showsConnection: { totalCount: 0 },
counts: { articles: 0, relatedArtists: 0 },
counts: { articles: 0, relatedArtists: 0, artworks: null },
related: { genes: { edges: [] } },
}),
})
Expand Down
Loading