Front-End Web & Mobile
How to build a Chrome extension that integrates with Amplify resources
AWS Amplify is the fastest and easiest way to build cloud-powered mobile and web apps on AWS. Amplify comprises a set of tools and services that enables front-end web and mobile developers to leverage the power of AWS services to build innovative and feature-rich applications.
Chrome extensions are a great way to build mini applications that utilize the browser functionality to serve content to users. These extensions provide the means for additional functionality by allowing ways to configure and embed information into a webpage. When combining the power of AWS cloud-based services and Chrome browser functionality, we can customize applications to increase productivity and decrease development time.
Chrome extension
The following example outlines a use case of adding an extension to a specific URL/webpage. This allows users who are using the extension to add images. For example, if we would like to take a screenshot of text or activities on the page that allows users to store the images, then the user has a catalog of images that they can refer back to upon revisiting the page. The extension harnesses the Amplify-provided resource by adding an Amazon Simple Storage Service (Amazon S3) bucket to store the images and Amplify UI component to display the images.
The application utilizes the latest chrome manifest V3 to create an extension, and it’s developed using the React JavaScript library with Amplify resources to provide functionality.
The Chrome extension manifest is an entry point that contains three main components.
- The Popup scripts
- Content scripts
- Background scripts
The Popup scripts are elements visible to the user when they select an extension. Content scripts are elements that run in a web page that let us make, modify, or add functionality to the web pages. Background scripts or service workers are event-based programs that let us monitor and send messages to other scripts.
In this application, we’ll be utilizing the Content script to modify a web page by adding an upload button and display an image.
For detailed information refer to the Chrome Documentation.
AWS Amplify
AWS Amplify is a set of purpose-built tools and features that lets frontend web and mobile developers quickly and easily build full-stack applications on AWS. This also includes the flexibility to leverage the breadth of AWS services as your use cases evolve.
The Amplify Command Line Interface (CLI) is a unified toolchain to create, integrate, and manage the AWS cloud services for your app.
We’ll utilize Amplify CLI to add Amazon S3 storage and Authentication capabilities. Additionally, we’ll use Amplify UI components to add a picker component.
Architecture
Walkthrough
In this application we create a post build script that modifies the manifest file on each build. The post build script copies the file names of JS and CSS files needed for the content script to append HTML elements to a page.
The following information outlines the steps needed in creating an Amplify chrome extension:
- Create a React project and install the necessary packages
- Create a Post build script and Manifest
- Add Amplify resources
- Add code to inject the HTML elements
- Test the application in the Chrome browser
Find the GitHub repository here.
Prerequisites
The following prerequisites are required for this post:
- An AWS account
- NPM
Setup a new React project
Let’s create a react project and install the necessary packages by running the following commands:
npx create-react-app AmplifyExtension
cd AmplifyExtension
Next, we’ll install packages necessary for the application, such as Amplify CLI, Amplify UI, and tiny-glob packages. We use the Amplify UI and tiny-glob package, as this enables us to decrease development time. The scripts and UI components can be replaced with your preferred elements.
npm install -g @aws-amplify/cli
npm install aws-amplify @aws-amplify/ui-react
npm install tiny-glob
Create a Post build script and Add Manifest
Create a folder named scripts at the root of the React application.
In the scripts folder, create a file called postbuild.js
and paste the following code:
const fs = require("fs");
const path = require('path')
const glob = require("tiny-glob");
const manifest = require("../public/manifest.json");
async function getFileNames(pattern) {
const files = await glob(`build/static${pattern}`)
return files.map(file => path.posix.relative('build', file.split(path.sep).join(path.posix.sep)));
}
async function main() {
const js = await getFileNames('/js/**/*.js')
const css = await getFileNames('/css/**/*.css')
const logo = await getFileNames('/media/logo*.svg')
const newManifest = {
...manifest,
content_scripts: [
{
...manifest.content_scripts[0],
js,
css,
},
],
web_accessible_resources: [
{
...manifest.web_accessible_resources[0],
resources: [...css, ...logo],
},
],
};
console.log('WRITING', path.resolve("./build/manifest.json"))
fs.writeFileSync(
path.resolve("./build/manifest.json"),
JSON.stringify(newManifest, null, 2),
'utf8'
);
}
main();
Open the package.json
file present at the root of the project and add the following to the scripts block:
"postbuild": "node ./scripts/postbuild.js"
The end result should appear as follows:
Add the following to the manifest.json
present in the public folder at the root of the application:
{
"manifest_version": 3,
"name": "React Content Script",
"version": "0.0.1",
"content_scripts": [
{
"matches": ["https://docs.amplify.aws/"],
"run_at": "document_end",
"js": [],
"css": [],
"media": []
}
],
"web_accessible_resources": [
{
"resources": [],
"matches": ["<all_urls>"]
}
]
}
Add Amplify resources
Let’s initialize the application with Amplify CLI. Run the command:
amplify init
Select the prompts.
? Enter a name for the project: AmplifyExtension
The following configuration will be applied:
Project information
| Name: AmplifyExtension
| Environment: dev
| Default editor: Visual Studio Code
| App type: javascript
| Javascript framework: react
| Source Directory Path: src
| Distribution Directory Path: build
| Build Command: npm.cmd run-script build
| Start Command: npm.cmd run-script start
? Initialize the project with the above configuration? (Y/n) Y
Next let’s add Cognito as the authenticator resource for login. Run the command:
amplify add auth
Select the following prompts:
Do you want to use the default authentication and security configuration? Default configuration
How do you want users to be able to sign in? Username
Do you want to configure advanced settings? No, I am done.
Let’s add an S3 bucket to our application. Run the command:
amplify add storage
Select the Prompts:
Select Content (Images, audio, video, etc.)
for who should have access, select: Auth users only
What kind of access do you want for Authenticated users? · create/update, read
To create the resources in the cloud, run the following command:
amplify push
Then, select yes
when prompted.
Add code to inject the HTML elements
Add the following to the Index.js
file present under the src folder:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
//find the body element
const body = document.querySelector('body');
//create div element
const app = document.createElement('div');
app.id = 'root';
if (body) {
body.prepend(app);
}
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
Next add the following to the App.js
file in the src folder:
import logo from './logo.svg';
import './App.css';
import { Amplify } from 'aws-amplify';
import { withAuthenticator } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';
import { AmplifyS3Album } from '@aws-amplify/ui-react/legacy';
import awsExports from './aws-exports';
Amplify.configure(awsExports);
function App() {
return (
<div className="App">
<header className="App-header">
<p>Hello</p>
<AmplifyS3Album />
</header>
</div>
);
}
//withAuthenticator component
export default withAuthenticator(App);
Test the Application in a Chrome browser
Run the following command to build the application:
npm run build
To test on a browser
- Open the Chrome browser.
- Open extensions in the Chrome settings.
- In the right side top of the screen, toggle developer mode on.
- Select load unpacked and select the location for the build folder of the application. This is present in the root of the React application and gets generated on a build command.
- Open https://docs.amplify.aws/ in a new tab and observe the following at the top of the page:
- Create an account. Note that you must provide a valid email, as a verification code will be sent.
- Upon logging in, the page will load a Button at the top.
- Upon selecting the
Pick a file
button and selecting a picture from your file system, we’ll observe the output as follows.
In the background, the picture is being uploaded to an S3 bucket and then displayed here.
Cleanup resources
Now that you’ve finished this walkthrough solution, you can delete your Amplify application if you aren’t going to use it anymore. Run the following command in the terminal at the root of the project.
amplify delete
Note that this action can’t be undone. Once the project is deleted, you can’t recover it. If you need it again, then you must re-deploy it.
To prevent any data loss, Amplify doesn’t delete the Amazon S3 storage bucket created via the CLI. We can delete the bucket on the Amazon S3 console. Note that the bucket will contain the name of the application (for example: AmplifyExtension), and it can be used when searching.
Delete the extension from the Chrome browser.
Conclusion
We can create Chrome extensions that allow users to consume Amplify resources, such as Amazon S3 storage and AWS Cognito. Furthermore, we can also utilize AppSync API capabilities to retrieve data from an Amazon DynamoDB Database.
A sample application can be found on Github here.
About the author: