Skip to content

Instantly share code, notes, and snippets.

@zchsh
Last active January 22, 2020 20:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zchsh/dbbefa2a8a1b51174947f970837d6c6e to your computer and use it in GitHub Desktop.
Save zchsh/dbbefa2a8a1b51174947f970837d6c6e to your computer and use it in GitHub Desktop.

Overview

This proposal is intended to address some pain points we've experienced around managing image asset files, specifically vector assets, and in consuming those files in our web projects.

👉 Note: Further context on the perceived need for this proposal can be found in another document on the background for vector asset needs. It's probably worth reviewing that document before this one, in case there are any needs that are inaccurate or missing.

Scope

What image assets are we talking about?

Generally, the proposed approach will try to address any vector asset that meets all of the following criteria:

  • best represented as an SVG original
  • should be consistent, and design would ideally update it globally all at once
  • re-used more than once or twice
  • has one or more digital mediums in which we want to use it (perhaps also non-digital uses, and perhaps even outside the digital team)

Specifically, the vector asset collections below meet the above criteria, and are what are being proposed for initial inclusion:

  • icons - our icon library, currently mostly Feather icons, with some customizations and additions
    • currently many icons are .svg files within web projects, and sometimes also stored in Dato. This makes them difficult to keep in sync, and makes it difficult to smoothly roll out updates to any individual icon.
  • product logos
  • corporate logos
    • same notes as on product logos, this just refers to logos for HashiCorp more broadly. For now this is literally just the HashiCorp logo and icon, but could see it expanding eg HashiConf logos, perhaps internal logos, etc.
  • companies logos - (specifically companies we partner with)
    • these logos are showcased across various parts of our sites. Our Dato collection currently requires the upload of color, black, and white logo versions, and recommends .svg formats, with the intention of making the logo entries usable in a variety of "themed" contexts. However the upload requirements aren't always feasible for members of the partner team, so we've ended up with what's actually a fairly unreliable collection. In addition, we can't enforce aspect ratios on uploaded images, which makes it very difficult to give a decent relative scale to these logos when they appear in a grid.
  • social icons
    • these are used in quite a few places, and it seems helpful to have a canonical reference for which versions we're using

What image assets are outside the scope of this proposal?

Anything that meets any of the following criteria:

  • One-time use image assets (such as page-specific illustrations or diagrams)
  • Non-vector image assets (such as photos, even if they are re-used across the site)

In addition, there are vector assets that meet the criteria for inclusion (such as diagram pieces), but which we don't want to try to address right now.

Note: while it's possible we could explore storing other assets, including "out of scope" ones, in the future, they just feel out of scope for now. We'd also likely want to evaluate a more traditional digital asset management system, or even just re-up on our DropBox organization, before including them.

Proposed Approach

The proposed setup is to place original SVG artwork in a GitHub repository, organized by:

  • collection
    • initially would be one of companies|corporate|icons|product|social
    • could add more collections quite easily, as needed
  • asset - the name of the image asset - for example arrow-down or consul-logo
    • adding an asset just means dropping some filed in the associated collection folder
  • variant - one of color|black|white
    • we could add additional variants if we want, though not as trivial as adding new assets or collections
    • an example might be different sizes of icons, eg 12px / 24px. But we may prefer to capture such examples in additional collections, eg icons-12px / icons-24px

For details on the proposed setup, see the proof of concept PR / branch on the @hashicorp/mktg-assets repo.

Note on "variants": not all assets contain each variant, for example icons only contain black variants at present.

Proposed Formats and Consumption

Plain .svg import

import urlSvg{Asset} from '@hashicorp/mktg-assets/{collection}/{asset}/{variant}.svg'
  • With our current NextJS setup, I believe this will load as a URL string to the .svg asset, meaning it would then likely be used with an <img> tag.
  • This may be a preferred option for cases where we have a large number of logos, which would like to avoid inline-ing to reduce initial page size.
import urlSvgArrowDown from "@hashicorp/mktg-assets/icons/arrow-down/black.svg";

function Demo() {
  return <img src={urlSvgArrowDown} title="arrow-down icon" />;
}

React <svg>

import Svgr{Asset} from `@hashicorp/mktg-assets/{collection}/{asset}/{variant}.jsx`
  • Saves us the <div> wrapper that <InlineSvg> creates
  • Easier to select & style the SVG element (CSS / GPS)
  • Removes need for dangerouslySetInnerHtml
import SvgrArrowDown from "@hashicorp/mktg-assets/icons/arrow-down/black.jsx";

function Demo() {
  return <SvgrArrowDown />;
}

React <svg> with autofix wrapper

import Svgr{Asset} from '@hashicorp/mktg-assets/{collection}/{asset}/{variant}__autofix.jsx'
  • Allows to set height: Npx; and width: auto; on a .g-svg-autofix-canvas wrapper element, and scaling works as expected in all browsers
  • See background for vector asset needs for details on this issue (shoutout to Jonathan for tuning us into the canvas fix!)
  • This need comes up with relatively high frequency with product logos, as we often want to set a fixed height on our logos when displayed alongside each other. Because our logos have different aspect ratios, we need to be able to set to achieve this.
import SvgrArrowDown from "@hashicorp/mktg-assets/icons/arrow-down/black__autofix.jsx";

function Demo() {
  return <SvgrArrowDown />;
}

Proposed Approach to Partner Assets

The proposed approach to partner assets would be for uploaded logos from the Dato organizations model to be used exclusively for partners and integrations views.

Specifically, logos pulled from that Dato collection would be used for https://www.hashicorp.com/integrations/ and https://www.hashicorp.com/ecosystem/find-a-partner.

It's worth noting that many of the logo grids on our marketing pages are already pulling from static assets within projects rather than from Dato. For example, the logos on the current homepage are files sitting within hashicorp-www-next. So the proposed approach in these cases won't affect Dato, it'll just give us an easier way to access commonly re-used assets.

This is the proposed approach for a few reasons:

  • It aligns with the editing needs the Partner's team expressed. They want quick and easy control over integration pages, and are less concerned with controlling logo grids in marketing contexts
  • It would allow us to remove the black and white upload fields from the organizations model, which are often misused for the very practical reason that it's often unfeasible for Partner folks to come up with those logo variations
  • It would allow us to remove the requirement to upload an svg logos. Partner and integration contexts will work well with reasonbly high resolution png logos. These are already used in many places since we can't catch file extension workarounds to the upload requirement such as my-shoehorned-logo.png.svg.
  • It would give us more granular control in all cases except partners and integrations. These are high-visibility applications such as logo grids and case studies on marketing pages. Having a design-controlled collection of logos with consistent aspect ratios in optimized formats will make it easier for developers to style these types of sections. It will also allow us to fix design nits like inconsistent logo scaling (due to unpredictable formats and sizes coming from Dato).

With respect to exposing logo fields to Dato in other contexts, the proposed approach is to set up custom fields on a per-page basis. We would manually restrict a short text field to all logo slugs that would be valid in the context of that specific page.

This proposed approach aligns with the need to keep tighter restrictions on who we show on logo grids in marketing contexts.... That is, just because a company is a partner and in the organizations collection in Dato, or just because we have their logo in this proposed assets repo, it doesn't mean they've approved use of their logo in marketing contexts. Giving CMS authors the full list to choose from feels kind of dangerous, while giving them a custom one-off list of slugs to choose from fits our needs very well, and doesn't take much effort.

Note: We could also of course not expose those things at all in the CMS, and just pass em in to the component in code, which would arguably take even less effort for a developer, and seems to be the kind of setup we currently have for the home page.

Discussion

  • Package name:

    The current name mktg-assets feels a bit vague. Maybe we rename the repo & npm package to @hashicorp/mktg-image-assets? Open to ideas, I think that suggestion came up in earlier discussion and it does feel more precise.

  • Shipping autofix React SVGs

    We'd discussed not distributing these versions, but this feels a bit too far on the "don't use these" side of things- there are common use cases for the product logo versions. However shipping __autofix versions for ALL assets definitely also feels like overkill.

    The autofix solution is only needed in a few specific use cases. Maybe we only generate __autofix versions for very specific assets for now? Maybe there's like a JSON file in the project that specifies which assets those are, by their {collection}/{asset} path?

Future Improvements

While out of scope for the initial implementation, wanted to make a note of some ideas that have come up:

  • Sync with organizations collection in Dato

    • Maybe every time an update is maybe to a record in that collection, file a GitHub issue?
    • Maybe populate the Dato collection using assets from the repo automatically? Or maybe it's safer to just do that manually?
    • Maybe there's a separate collection in Dato that exposes all the available companies/{asset} slugs? And maybe that gets updated automatically?
  • Add search functionality to the asset download view (labrador-buyout-insurer)

    • Having a big grid of assets is a start, but search would make things much easier to find
    • Might actually be useful early in the process, to determine what has / hadn't been added

Discarded Ideas

  • Ship string versions of the SVGs

    Previously this proposal suggested we might ship Javascript modules that export the SVG as a flat string alongside our other formats.

    This idea is no longer part of the proposal because it seems preferable to use SVGR React components, rather than have to dangerouslySetInnerHtml to get the string version of the SVG onto the page.

    If we want to explore support for frameworks other than React, this idea might be worth revisiting.

    import svg{Asset} from '@hashicorp/mktg-assets/{collection}/{asset}/{variant}.js'
    • Fairly straightforward, exports a string of the <svg> source.
    • Providing this as an option in case it ever makes sense for use in another framework (Ember?) and in case we ever want to use this with <InlineSvg />.
    import InlineSvg from "@hashicorp/react-inline-svg";
    import svgArrowDown from "@hashicorp/mktg-assets/icons/arrow-down/black.js";
    
    function Demo() {
      return <InlineSvg src={svgArrowDown} />;
    }
  • Ship PNG versions in the package

    Previously this proposal suggested we might ship PNG versions as part of the published package.

    This idea is no longer part of the proposal because of all the assets in the repo will have SVG originals, and there doesn't seem to be a current use cases where using a .png src for an image would be preferable to using an .svg src.

    import urlPng{Asset} '@hashicorp/mktg-assets/{collection}/{asset}/{variant}.png'
    • Very similar to the Plain .svg import option.
    • As with that example, this is likely not an option that we'll reach for often. It's mainly intended for use in the web view of these assets, as the .png format is highly portable (can be used in Google Docs, slides, diagramming tools, and so on).
    • Maybe we don't build this for distribution on npm? And instead just use the .png versions as easy downloads on the web view?
    import urlPngArrowDown from "@hashicorp/mktg-assets/icons/arrow-down/black.png";
    
    function Demo() {
      return <img src={urlPngArrowDown} title="arrow-down icon" />;
    }

Other ideas?

Maybe there's an entirely different way to approach this problem? Would something like svg-react-loader be worth considering? Maybe there are gaps in this plan that we need to talk about? Open to any and all ideas.

@jescalan
Copy link

This is looking excellent to me. I can't think of any areas to be improved. Great work 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment