Edit in GitHubLog an issue

Add a new environment variable

Environment variables provide values that may vary across different instances of the same project. The value of this variable can vary between development, staging, and production environments.

Background#

In PWA Studio storefront projects, the .env file in the project's root directory lists the environment variables and their values. For example, the MAGENTO_BACKEND_URL environment variable tells your storefront project which Adobe Commerce or Magento Open Source instance it uses during runtime. These variables are available to your Node scripts, but for security reasons, PWA Studio limits which variables your frontend code can access.

This tutorial teaches you how to create a package which provides a React component that uses an environment variable.

Tasks overview#

  1. Initialize the project
  2. Create the PlaceholderImage component
  3. Create and register the intercept file
  4. Define the intercept file
  5. Test on a local instance

Initialize the project#

Use npm init or yarn init to create a new JavaScript package project for this tutorial. Since this is a standalone project, you do not need to create this inside a storefront project.

Edit the package.json file so it looks like the following:

Copied to your clipboard
1{
2 "name": "PlaceholderImage",
3 "version": "1.0.0",
4 "license": "MIT",
5 "peerDependencies": {
6 "@magento/pwa-buildpack": "^7.0.0",
7 "@magento/venia-ui": "^5.0.0",
8 "react": "^16.14.0"
9 }
10}

Create the PlaceholderImage component#

Create a React component that renders an image from an image placeholder service source provided by an environment variable.

Copied to your clipboard
mkdir -p src/components/PlaceholderImage && touch src/components/placeholderImage.js

Inside the placeholderImage.js, add the following content:

Copied to your clipboard
1import React from "react";
2
3const PlaceholderImage = (props) => {
4 const { width = 300, height = 300 } = props;
5
6 const urlTemplate = process.env.IMAGE_PLACEHOLDER_SERVICE_URL;
7
8 if (!urlTemplate) {
9 console.error("Image placeholder service not defined!");
10 return null;
11 }
12
13 const finalUrl = urlTemplate.replace("${w}", width).replace("${h}", height);
14
15 return <img src={finalUrl} />;
16};
17
18export default PlaceholderImage;

The PlaceholderImage component uses the value of the IMAGE_PLACEHOLDER_SERVICE_URL environment variable as a template for the final image source url. It replaces instances of ${w} and ${h} in the template with the width and height prop values.

Most image placeholder services let you specify the image dimensions in the url but in different ways. For example, a 300x400 image request can look like <url>/300/400 or <url>/300x400. This template approach adds support for these different services by letting you specify what the final URL looks like.

Make the component importable#

To use this component in other projects, you must export it from this package, so make the following modifications to the package.json file:

Copied to your clipboard
1 {
2 "name": "PlaceholderImage",
3 "version": "1.0.0",
4 "license": "MIT",
5+ "main": "src/components/PlaceholderImage/placeholderImage.js",
6 "peerDependencies": {
7 "@magento/pwa-buildpack": "^7.0.0",
8 "@magento/venia-ui": "^5.0.0",
9 "react": "^16.14.0"
10 }
11 }

Create and register the intercept file#

You can create the intercept file anywhere in your project. For this tutorial, create this file under src/targets.

Copied to your clipboard
mkdir -p src/targets && touch src/targets/intercept.js

Set the value for pwa-studio.targets.intercept in your project's package.json file to tell the build process where to find the intercept file.

Copied to your clipboard
1 {
2 "name": "PlaceholderImage",
3 "version": "1.0.0",
4 "license": "MIT",
5 "main": "src/components/PlaceholderImage/placeholderImage.js",
6 "peerDependencies": {
7 "@magento/pwa-buildpack": "^7.0.0",
8 "@magento/venia-ui": "^5.0.0",
9 "react": "^16.14.0"
10- }
11+ },
12+ "pwa-studio": {
13+ "targets": {
14+ "intercept": "src/targets/intercept"
15+ }
16+ }
17 }

Define the intercept file#

The intercept file is where you tap into PWA Studio's extensibility framework and add your modifications.

In your intercept file, add the following content:

Copied to your clipboard
1module.exports = (targets) => {
2 const buildpackTargets = targets.of("@magento/pwa-buildpack");
3
4 buildpackTargets.envVarDefinitions.tap((defs) => {
5 defs.sections.push({
6 name: "PlaceholderImage settings",
7 variables: [
8 {
9 name: "IMAGE_PLACEHOLDER_SERVICE_URL",
10 type: "str",
11 desc: "Service URL for image placeholders",
12 },
13 ],
14 });
15 });
16
17 buildpackTargets.specialFeatures.tap((featuresByModule) => {
18 featuresByModule["PlaceholderImage"] = {
19 esModules: true,
20 };
21 });
22};

When this file runs, it taps into the envVarDefinitions target from the available targets in @magento/pwa-buildpack and passes in an intercept function. The intercept function appends a new definition to the core environment variable definitions, which allows frontend code access to the IMAGE_PLACEHOLDER_SERVICE_URL environment variable.

Test on a local instance#

Install this package in a local storefront project to use the PlaceholderImage component.

Copied to your clipboard
yarn add --dev link:/path/to/your/project

This adds a devDependencies entry to your storefront project's package.json that looks like the following:

Copied to your clipboard
1 "@storybook/react": "~5.2.6",
2+ "PlaceholderImage": "link:/path/to/your/project",
3 "apollo-cache-persist": "~0.1.1",

Create environment variable entry#

In your project's .env file, create an entry for IMAGE_PLACEHOLDER_SERVICE_URL.

Copied to your clipboard
IMAGE_PLACEHOLDER_SERVICE_URL=http://www.loremflickr.com/${w}/${h}

The PlaceholderImage component uses this value to compute the source when it renders the image.

Create a demo page#

Create a demo page component to render the ImagePlaceholder component.

Copied to your clipboard
mkdir -p src/components/PlaceholderImageDemo && touch src/component/PlaceholderImageDemo/placeholderImageDemo.js

Inside placeholderImageDemo.js, add the following content:

Copied to your clipboard
1import React from "react";
2import PlaceholderImage from "PlaceholderImage";
3
4const PlaceholderImageDemo = () => {
5 return <PlaceholderImage width={200} height={300} />;
6};
7
8export default PlaceholderImageDemo;

Add a static route#

If you used the project scaffolding tool in PWA Studio 8.0.0 or above, your project will have a local-intercept.js file. If you do not have this file, use the same earlier steps to create and register the intercept file.

Inside your storefront's intercept file, add the following content to add a new static route for your demo page:

Copied to your clipboard
1function localIntercept(targets) {
2 targets.of("@magento/venia-ui").routes.tap((routes) => {
3 routes.push({
4 name: "Placeholder Image demo page",
5 pattern: "/placeholder-image-demo",
6 exact: true,
7 path: require.resolve(
8 "./src/components/PlaceholderImageDemo/placeholderImageDemo.js"
9 ),
10 });
11 return routes;
12 });
13}
14
15module.exports = localIntercept;

Check out the page#

Now, when you start your project, you can navigate to /placeholder-image-demo and see the PlaceholderImage component in action.

  • Privacy
  • Terms of Use
  • Do not sell my personal information
  • AdChoices
Copyright © 2022 Adobe. All rights reserved.