Skip to content

Support Watermark image

shraddha-kesari edited this page Mar 16, 2023 · 2 revisions

Stories that are shared on social media can have watermark on the hero image

Watermarks are configured in Bold Editor, each section can have a watermark image associated with it, if not , global watermark will be picked for that story.

storyApi response gives watermark object which has social > image-s3key

By default, the watermark is enabled for all the stories, and we can disable the watermark of a particular story through Bold

Need to update the imageUrl under SEO Image tags (by overlaying watermark at the bottom of hero image of the story ) based on toggles (enableTwitterCards and enableOgTags) under seoConfig in app.js file of your app.

This updates og:image metatag of the story page

Custom watermark image generator

  1. create a file named image-tag-generator.js with the below code snippet
import get from "lodash/get";
import { FocusedImage } from "quintype-js";

import { ImageTags } from "@quintype/seo";
import { getPublisherAttributes } from "../load-data";

export const imageTagGenerator = () => {
  return (seoConfig, config, pageType, data, { url = {} }) => {
    const publisherConfig = getPublisherAttributes(config);
    const imageCdnSrc = publisherConfig.cdn_src;
    const imageCdnUrl = publisherConfig.cdn_image;
    const isWatermarkDisabled = get(data, ["data", "story", "metadata", "watermark-image", "disabled"], false);

    let imageTags = ImageTags(seoConfig, config, pageType, data, { url });

    if (pageType === "story-page") {
      function pickImageFromStory() {
        const story = data.data.story;
        function getAlt(type, key, fallback) {
          return get(story, ["alternative", `${type}`, "default", "hero-image", `${key}`], fallback);
        }

        const altHeroImg = getAlt("home", "hero-image-s3-key", null);
        const altSocialHeroImg = getAlt("social", "hero-image-s3-key", null);
        const storyHeroImage = get(story, ["hero-image-s3-key"], null);
        const fallbackSocialImage = get(seoConfig, ["fallbackSocialImage"], null);

        if (altSocialHeroImg) {
          const metadata = getAlt("social", "hero-image-metadata", {});
          return new FocusedImage(altSocialHeroImg, metadata);
        } else if (altHeroImg) {
          const metadata = getAlt("home", "hero-image-metadata", {});
          return new FocusedImage(altHeroImg, metadata);
        } else if (storyHeroImage) {
          const metadata = get(story, ["hero-image-metadata"], {});
          return new FocusedImage(storyHeroImage, metadata);
        } else if (fallbackSocialImage) {
          return fallbackSocialImage;
        } else {
          return null;
        }
      }

      const imageContentParams = (imageRatio) => {
        const imageContentParamsObj = {
          w: 1200,
          ar: imageRatio.join(":"),
          auto: "format,compress",
          ogImage: true,
          mode: "crop",
        };

        const renderWatermarkImage = (story, cdnUrl, imageCdnSrc) => {
          const watermarkImageS3Key = get(story, ["watermark", "social", "image-s3-key"], "");
          if (imageCdnSrc.includes("gumlet") && watermarkImageS3Key.length > 0) {
            return `https://${cdnUrl}/${watermarkImageS3Key}`;
          }
          return watermarkImageS3Key;
        };

        const overlayInfo = {
          overlay: renderWatermarkImage(data.data.story, imageCdnUrl, imageCdnSrc),
          overlay_position: "bottom",
        };

        const overlayInfoUpdated = imageCdnSrc.includes("gumlet")
          ? { ...overlayInfo, ...{ overlay_width_pct: 1 } }
          : { ...overlayInfo, ...{ overlay_width: 100 } };

        const imageContentParamsObjUpdated =
          !isWatermarkDisabled && pickImageFromStory() && pickImageFromStory().path
            ? { ...imageContentParamsObj, ...overlayInfoUpdated }
            : { ...imageContentParamsObj };
        return `https://${imageCdnUrl}/${pickImageFromStory().path(imageRatio, imageContentParamsObjUpdated)}`;
      };

      const storyTwitterImage =
        pickImageFromStory() && pickImageFromStory().path ? imageContentParams([40, 21]) : "";
      const storyOgImage =
        pickImageFromStory() && pickImageFromStory().path ? imageContentParams([40, 21]) : "";

      imageTags.forEach((imageTag, index) => {
        if (seoConfig.enableTwitterCards && imageTag.name === "twitter:image") {
          imageTag.content = storyTwitterImage;
        }

        if (seoConfig.enableOgTags && imageTag.property === "og:image") {
          imageTag.content = storyOgImage;
        }
      });

      imageTags = imageTags.filter(
        (imageTag) => imageTag.property !== "twitter:image:alt" && imageTag.property !== "og:image:alt"
      );
    }

    return imageTags;
  };
};
  1. import this file in server/app.js file.

  2. And call the imageTagGenerator() function inside SEO generator like below

function generateSeo(config, pageType) {
  return new SEO({
    staticTags: Object.assign(generateStaticData(config)),
    structuredData: Object.assign(generateStructuredData(config), {
      ...
    }),
    ...
    generators: [TextTags, imageTagGenerator(), AuthorTags, StaticTags, StructuredDataTags, StoryAmpTags],
  });
}
Clone this wiki locally