On select occasions since 2015, Artsy Editorial has created a number of custom, one-off articles featuring unique layouts, styles and experiences. After trying a number of implementations, the EditorialFeature
component was introduced to the process during Artsy’s 2018 year-in-review projects.
By moving the implementation of custom articles to Artsy’s component library, we were able to remove some of the friction and time investment necessary for engineers to spin up these articles, and enable bespoke layouts to be housed in Artsy.net’s Article domain rather than a custom Express app. Acting essentially as a wrapper to accept article data, any component can be rendered as a child of the EditorialFeature
component, allowing for flexible combinations of new and existing features, and for minimal or maximal interventions.
For a light-weight customization, a developer might add props for unique text or background colors. Medium-touch could involve wrapping an existing layout in a styled-component declaring further css interventions to font-size, borders, margins or other layout properties. The space is an open canvas, so the option is available to build every element from scratch, introduce JS interactivity, and to interact with any data saved to the article model in a completely new way. The scale of a project can vary widely, but determined by weighing priorities of editorial intent, proposed designs, engineering capabilities/availability, and budget.
Some examples of articles created with the EditorialFeature
component include:
-
The Most Influential Artists of 2018 - Components Article -
The Year in Visual Culture 2018 - Components Article
Custom articles by domain:
- Whether an article requires a custom layout is determined in Force’s article routing. This is achieved by passing the prop
customEditorial
– a string shorthand for a specific article– to Reaction’s top-levelArticle
component. ThecustomEditorial
prop is pulled from Force’s editorial feature “master list”, which ties anarticle._id
to a communicative string that will be received by Reaction. In addition to data saved to an article model, the component will also receive all data displayed in the footer including related articles and display ads. Custom articles are rendered as a standalone page, meaning they are excluded from infinite scroll and do not render the main site header.
2. In Reaction (Artsy’s component library)
- In Reaction’s top-level
Article
component, the presence of acustomEditoral
prop routes an article to theArticleWithFullScreen
component. From here, the article is given context for image slideshows and tooltip helpers, and theEditorialFeature
component is rendered rather than the component designated by the article’s specified layout. AFeatureLayout
is displayed by default, but any article can be converted into a custom feature, regardless of thearticle.layout
value. Inside theEditorialFeature
component, a switch statement is used to associate the string variable for the feature with its affiliated top-level component.
3. In Writer/Positron (CMS & API for articles)
- Because
EditorialFeature
accepts an article data-model, it can be edited using the Writer CMS. However it is important to note that a custom layout is rendered by Force only. While editing, what users see is dicated by thearticle.layout
property. Writer’s features are exposed based on this property, so a particular custom article’s layout should be determined by the features most suited to the content and design. For example, if you need a header-image or video, a feature article would be a logical choice because that content can easily be created and edited in Writer. If the article relies heavily on content from related articles, you might choose to customize a series article instead.
Creating a custom feature
A custom layout is enabled via three steps:
- Add a new object to the
customEditorialArticles
master list, indicating thearticle._id
andname
. Names are usually a shorthand for the content, and used because they are descriptive (unlike an_id
), and will not change over time like a title or slug has potential to do.{ name: "MY_CUSTOM_FEATURE", id: "12345" // mongo _id }
- Create your custom component in the
EditorialFeature/Components
directory - Add your
customEditorial
string toEditorialFeature
’s switch statement to enable rendering custom componentcase "MY_CUSTOM_FEATURE": { return <MyCustomFeature {...props} /> }
Although these features historically receive high traffic via search and other channels, they usually have little internal visibility a few months after they are published. For this reason it is recommended that, in addition to any unit tests, developers create a snapshot of the custom article so that unexpected regressions are flagged in a test failure.
History & Context
Previously we have used multiple strategies to implement these features, using two sometimes overlapping concepts: Curations and SuperArticles.
Curations:
A Curation is a model in Positron’s API that has no schema– meaning it accepts any data shape. This can be a handy solution for content that does not conform to the existing article model. However, this strategy comes with significant overhead and a few quirks:
- A custom edit UI must be created and maintained indefinitely
- A custom Express app is required by Force to render the content
- Because data is in a unique shape, components often must be fully custom
- It is difficult to track visual changes over time
Despite these pitfalls, Curations remain useful for special cases, especially those which involve interactive navigation through content.
Published examples of custom articles that use curations are:
See previous blog post on creating The Year in Art 2016.
SuperArticles:
An article where the is_super_article
field is set to true includes the ability to attach related articles and sponsor-related fields to an article. It also exempts an article from the infinite scroll feed, and renders a custom header (in place of the main site navigation) and footer. The SuperArticle header and footer both include navigation options to view and visit related, aka sub-article, content.
The first SuperArticle was also the first custom feature, and its attributes were made available to all articles when launched. However, its weakness lies in a conflation of a series and a sponsor as a single concept. In practice we have seen that they are not mutually exclusive. Additionally, support for this feature was built in Backbone, and hasn’t always behaved as expected when inserted into our React-heavy ecosystem. Since the SuperArticle was created, we have extended the ability for any article to accept either or both sponsor and related article data, and we are currently in the process of deprecating this concept.
Existing SuperArticles include:
Takeaways for developers
- We try to work with our editorial and design teams to ensure new editorial content maps as closely to our existing article data-model and CMS features as possible. That way, we can have an upfront conversation about the constraints our systems might impose on designs.
- Relying heavily on existing article and system components ensures that system-wide changes (for example, changes to breakpoints) will be inherited
- Always create snapshot tests to monitor how an article changes over time