### Create Plasmo Extension with Example Template Source: https://docs.plasmo.com/framework/workflows/new Generate a new project based on an example template by using the `--with-env` flag. Note the `--` escape for npm. Supports pnpm and npm. ```bash pnpm create plasmo --with-env ``` ```bash npm create plasmo -- --with-env ``` -------------------------------- ### Start Plasmo Development Server Source: https://docs.plasmo.com/framework/workflows/dev Run this command in your project directory to start the development server. Plasmo will create a dev bundle and a live-reloading server, automatically updating your extension on file changes. ```bash pnpm dev ``` ```bash npm run dev ``` ```bash plasmo dev ``` -------------------------------- ### Start Plasmo Development Server Source: https://docs.plasmo.com/framework Run this command to start the development server, which provides live-reloading and React HMR for faster development cycles. The output will be generated in `build/chrome-mv3-dev`. ```bash pnpm dev ``` -------------------------------- ### Install @plasmohq/storage Source: https://docs.plasmo.com/framework/storage Install the Plasmo Storage library using pnpm. ```bash pnpm install @plasmohq/storage ``` -------------------------------- ### Install Firebase and Plasmo Packages Source: https://docs.plasmo.com/quickstarts/with-firebase-authentication Install the necessary packages for Firebase, Plasmo messaging, and Plasmo storage using npm, yarn, or pnpm. ```bash npm install firebase @plasmohq/messaging @plasmohq/storage ``` ```bash yarn add firebase @plasmohq/messaging @plasmohq/storage ``` ```bash pnpm install firebase @plasmohq/messaging @plasmohq/storage ``` -------------------------------- ### Example Usage of Local TypeScript Aliases Source: https://docs.plasmo.com/framework/customization/alias Demonstrates how to import components using the configured aliases from `@Components/`. ```typescript import { Button } from "@Components/button" import { Checkbox } from "@Components/checkbox" import { Header } from "@Components/header" import { Input } from "@Components/input" ``` -------------------------------- ### Install Plasmo CLI Source: https://docs.plasmo.com/quickstarts/migrate-to-plasmo Install the Plasmo CLI using pnpm. This command installs the Plasmo framework's core package, which includes the compiler, bundler, development server, and packager. ```bash pnpm install plasmo ``` -------------------------------- ### Example Plasmo Submission Credentials Source: https://docs.plasmo.com/framework/workflows/submit An example of a complete `keys.json` file including credentials for Chrome and Edge. This file should be added as a repository secret named `SUBMIT_KEYS` on GitHub. ```json { "$schema": "https://raw.githubusercontent.com/plasmo-corp/bpp/v3/keys.schema.json", "chrome": { "clientId": "123", "refreshToken": "789", "extId": "abcd", "clientSecret": "efgh" }, "edge": { "clientId": "aaaaaaa-aaaa-bbbb-cccc-dddddddddddd", "clientSecret": "abcdefg", "productId": "aaaaaaa-aaaa-bbbb-cccc-dddddddddddd", "accessTokenUrl": "https://login.microsoftonline.com/aaaaaaa-aaaa-bbbb-cccc-dddddddddddd/oauth2/v2.0/token" } } ``` -------------------------------- ### Install puro for Context Utility Source: https://docs.plasmo.com/quickstarts/with-stripe Add the puro library to your package.json to utilize Plasmo's context utility for managing application state. ```json { ... "dependencies": { ... "puro": "0.3.4" } } ``` -------------------------------- ### Example Usage of External TypeScript Module Alias Source: https://docs.plasmo.com/framework/customization/alias Shows how to import from an aliased external module. ```typescript import { hello } from "coolio/hello" ``` -------------------------------- ### Default Overlay Anchor Example Source: https://docs.plasmo.com/framework/content-scripts-ui/life-cycle Illustrates the default overlay anchor configuration, which uses document.body as the element. ```typescript { type: "overlay", element: document.body } ``` -------------------------------- ### Example Usage of External Alias Import Source: https://docs.plasmo.com/framework/customization/alias Demonstrates importing a module that has been aliased to an external file. ```typescript import { hello } from "some-cool-identifier/hello" ``` -------------------------------- ### Storage API - Basic Usage Source: https://docs.plasmo.com/framework/storage Demonstrates the basic usage of the Storage API for setting and getting data. It handles serialization and deserialization automatically for primitive types and plain objects. ```APIDOC ## Storage API - Basic Usage ### Description This section shows how to initialize and use the base Storage API to store and retrieve data. It supports various data types as long as they are serializable. ### Method N/A (This is a library usage example, not an HTTP endpoint) ### Endpoint N/A ### Parameters N/A ### Request Example ```javascript import { Storage } from "@plasmohq/storage" const storage = new Storage() await storage.set("key", "value") const data = await storage.get("key") // "value" await storage.set("capt", { color: "red" }) const data2 = await storage.get("capt") // { color: "red" } ``` ### Response N/A (This is a library usage example) ``` -------------------------------- ### Install Plasmo Messaging Dependency Source: https://docs.plasmo.com/framework/messaging Install the `@plasmohq/messaging` library using pnpm. This is the first step to enable messaging functionality in your Plasmo extension. ```bash pnpm install @plasmohq/messaging ``` -------------------------------- ### Build and Package Browser Extension with Plasmo Source: https://docs.plasmo.com/itero/test-bed Use these Plasmo CLI commands to build your extension for production and create a zip bundle for distribution. Ensure you have Plasmo installed and configured for your project. ```bash pnpm build ``` ```bash pnpm package ``` -------------------------------- ### Importing Raw Asset with URL Source: https://docs.plasmo.com/framework/import Use the 'raw' scheme to copy a file into the extension bundle and get its runtime URL. A content hash is assigned to the filename. ```typescript import imageUrl from "raw:~/assets/image.png" console.log(imageUrl) // chrome-extension:///image..png ``` -------------------------------- ### Manual Upload API - Step 1: Get Signed Upload URL Source: https://docs.plasmo.com/itero/api This endpoint issues a signed URL for uploading your extension's zip file to Itero. ```APIDOC ## POST /api/submit/upload ### Description Issues a signed URL for uploading your extension to Itero. ### Method POST ### Endpoint https://itero.plasmo.com/api/submit/upload ### Parameters #### Request Body - **keys.itero** (object) - Required - The `itero` object obtained from your downloaded API key JSON file. ### Request Example ```json { "itero": { "someKey": "someValue" } } ``` ### Response #### Success Response (200) - **url** (string) - The signed URL for uploading the zip file. #### Response Example ```json { "url": "signed-upload-url" } ``` ``` -------------------------------- ### Global Style Override Example Source: https://docs.plasmo.com/framework/content-scripts-ui/styling Demonstrates how a global '*' CSS selector can override the root container's display property. Use inline styles to maintain consistency. ```css * { display: block; } ``` -------------------------------- ### Basic Content Script Setup Source: https://docs.plasmo.com/framework/content-scripts A minimal content script requires an `export {{}}` to be treated as a module by Plasmo's default TypeScript configuration. This ensures it's recognized as a content script. ```typescript export {} console.log( "You may find that having is not so pleasing a thing as wanting. This is not logical, but it is often true." ) ``` -------------------------------- ### Dynamically Create Custom Container with getRootContainer Source: https://docs.plasmo.com/framework/content-scripts-ui/life-cycle Dynamically create a custom container by exporting `getRootContainer` and implementing logic to create and insert a new DOM element. This example uses `setInterval` to wait for an anchor element before creating and mounting the container. ```typescript import type { PlasmoRender } from "plasmo" import { CustomContainer } from "~components/custom-container" const EngageOverlay = () => ENGAGE // This function overrides the default `createRootContainer` export const getRootContainer = ({ anchor, mountState }) => new Promise((resolve) => { const checkInterval = setInterval(() => { let { element, insertPosition } = anchor if (element) { const rootContainer = document.createElement("div") mountState.hostSet.add(rootContainer) mountState.hostMap.set(rootContainer, anchor) element.insertAdjacentElement(insertPosition, rootContainer) clearInterval(checkInterval) resolve(rootContainer) } }, 137) }) export const render: PlasmoRender = async ({ anchor, // the observed anchor, OR document.body. createRootContainer // This creates the default root container }) => { const rootContainer = await createRootContainer(anchor) const root = createRoot(rootContainer) // Any root root.render( ) } ``` -------------------------------- ### Configure Web Accessible Resources in package.json Source: https://docs.plasmo.com/framework/assets Declare web-accessible resources in your `package.json` manifest override to make them available to `chrome.getURL()`. This example shows how to include raw JS files, PNG images matching a glob pattern, and JSON files. ```json "manifest": { "web_accessible_resources": [ { "resources": [ "~raw.js", "assets/pic*.png", "resources/test.json" ], "matches": [ "https://www.plasmo.com/*" ] } ], "host_permissions": [ "https://*/*" ] } ``` -------------------------------- ### Use User Info Context in Popup Source: https://docs.plasmo.com/quickstarts/with-stripe This example shows how to consume the UserInfo context in a React component to display the user's email. Ensure the UserInfoProvider wraps the components that need access to user data. ```typescript import { UserInfoProvider, useUserInfo } from "~core/user-info" const EmailShowcase = () => { const userInfo = useUserInfo() return (
Your email is: {userInfo?.email}
) } function IndexPopup() { return (

Welcome to your Plasmo Extension!

) } export default IndexPopup ``` -------------------------------- ### Basic Storage Operations Source: https://docs.plasmo.com/framework/storage Use the base Storage API to set and get serializable data. This API works across extension runtimes like background service workers and content scripts. ```typescript import { Storage } from "@plasmohq/storage" const storage = new Storage() await storage.set("key", "value") const data = await storage.get("key") // "value" await storage.set("capt", { color: "red" }) const data2 = await storage.get("capt") // { color: "red" } ``` -------------------------------- ### Combine Build and Package Process Source: https://docs.plasmo.com/framework/workflows/build To streamline the process, use the `--zip` flag with the `build` command to simultaneously build and package your project into a zip bundle. This works with both pnpm and npm. ```bash pnpm build --zip # OR npm run build -- --zip ``` -------------------------------- ### Create Production Build Source: https://docs.plasmo.com/framework/workflows/build Run this command to create a production bundle for distribution. Supports both pnpm and npm package managers. ```bash pnpm build # OR npm run build ``` -------------------------------- ### Initialize Supabase Client Source: https://docs.plasmo.com/quickstarts/with-supabase Set up the Supabase client in `core/supabase.ts` using environment variables for URL and Key. It configures storage, auto-refresh, and session persistence. ```typescript import { createClient } from "@supabase/supabase-js" import { Storage } from "@plasmohq/storage" const storage = new Storage({ area: "local" }) export const supabase = createClient( process.env.PLASMO_PUBLIC_SUPABASE_URL, process.env.PLASMO_PUBLIC_SUPABASE_KEY, { auth: { storage, autoRefreshToken: true, persistSession: true, detectSessionInUrl: true } } ) ``` -------------------------------- ### Initialize Tailwind CSS Configuration Source: https://docs.plasmo.com/quickstarts/with-tailwindcss Generate the `tailwind.config.js` and `postcss.config.js` files using the Tailwind CLI. ```bash npx tailwindcss init -p ``` -------------------------------- ### Import-Optimized Build Source: https://docs.plasmo.com/framework/workflows/build Generate a bundle that deduplicates and hoists your dependencies to the top for potentially faster bundling and smaller bundle sizes. Use the `--hoist` flag. ```bash plasmo build --hoist ``` -------------------------------- ### Storage API - Watching for Changes Source: https://docs.plasmo.com/framework/storage Demonstrates how to use the `watch` method to subscribe to changes in specific storage keys, enabling real-time state synchronization. ```APIDOC ## Storage API - Watching for Changes ### Description The `watch` method allows you to listen for changes to specific storage keys. This is crucial for synchronizing state across different parts of your extension. ### Method N/A ### Endpoint N/A ### Parameters #### `watch` Method Parameters - **callbackObject** (object) - An object where keys are the storage keys to watch and values are callback functions. Each callback receives a change object with `newValue` and `oldValue`. ### Request Example ```javascript import { Storage } from "@plasmohq/storage" const storage = new Storage() await storage.set("serial-number", 47) await storage.set("make", "plasmo-corp") storage.watch({ "serial-number": (c) => { console.log(c.newValue) }, make: (c) => { console.log(c.newValue) } }) await storage.set("serial-number", 96) await storage.set("make", "PlasmoHQ") ``` ### Response N/A **Note:** The Storage API is not available in a Content Script when it is executed in the 'MAIN' world. ``` -------------------------------- ### Build with Custom Environment File Source: https://docs.plasmo.com/framework/env Use the --env flag to specify a custom environment file that will be prioritized above all other environment configurations. ```bash plasmo build --env=.env.important ``` -------------------------------- ### Create New Plasmo Extension (Interactive) Source: https://docs.plasmo.com/framework/workflows/new Run the interactive initialization wizard to create a new Plasmo extension. Supports pnpm, yarn, and npm. ```bash pnpm create plasmo ``` ```bash yarn create plasmo ``` ```bash npm create plasmo ``` -------------------------------- ### Install Tailwind CSS Dependencies Source: https://docs.plasmo.com/quickstarts/with-tailwindcss Add Tailwind CSS, PostCSS, and Autoprefixer as development dependencies to your existing Plasmo project. ```bash pnpm i -D tailwindcss@3 postcss autoprefixer ``` -------------------------------- ### Build Plasmo Project for Production Source: https://docs.plasmo.com/framework Execute this command to create a production-ready build of your browser extension. The output will be located in `build/chrome-mv3-prod`. ```bash pnpm build ``` -------------------------------- ### Get Single Overlay Anchor Function Source: https://docs.plasmo.com/framework/content-scripts-ui/life-cycle Export a `getOverlayAnchor` function to specify a single overlay anchor element for mounting. ```typescript import type { PlasmoGetOverlayAnchor } from "plasmo" export const getOverlayAnchor: PlasmoGetOverlayAnchor = async () => document.querySelector("#pricing") ``` -------------------------------- ### Build with Source Maps Source: https://docs.plasmo.com/framework/workflows/build Enable the generation of source maps for your production bundle by using the `--source-maps` flag. This is useful for debugging. ```bash plasmo build --source-maps ``` -------------------------------- ### Usage in Extension Popup Page Source: https://docs.plasmo.com/quickstarts/with-tailwindcss Example of using Tailwind CSS classes directly within a React component for a Plasmo extension popup. ```typescriptreact import { useReducer } from "react" import "./style.css" function IndexPopup() { const [count, increase] = useReducer((c) => c + 1, 0) return ( ) } export default IndexPopup ``` -------------------------------- ### Custom Overlay Anchor Position Update Source: https://docs.plasmo.com/framework/content-scripts-ui/life-cycle Implement `watchOverlayAnchor` to customize how the overlay container refreshes its position, for example, by using `setInterval` to update position periodically. ```typescript import type { PlasmoWatchOverlayAnchor } from "plasmo" export const watchOverlayAnchor: PlasmoWatchOverlayAnchor = ( updatePosition ) => { const interval = setInterval(() => { updatePosition() }, 8472) // Clear the interval when unmounted return () => { clearInterval(interval) } } ``` -------------------------------- ### Initialize Plasmo Project with Supabase Source: https://docs.plasmo.com/quickstarts/with-supabase Use this command to create a new Plasmo project with Supabase integration pre-configured. ```bash pnpm create plasmo --with-supabase ``` -------------------------------- ### Configure Development Server Host and Port Source: https://docs.plasmo.com/framework/workflows/dev Customize the hostname and port for the development server using `--serve-host` and `--serve-port`. The default is `localhost` and port `1012`. ```bash plasmo dev --serve-host=localhost --serve-port=1012 ``` -------------------------------- ### Create Plasmo Project with src Directory Source: https://docs.plasmo.com/framework/customization/src Use this command to initialize a new Plasmo project with the source code automatically placed in a 'src' directory. ```bash pnpm create plasmo --with-src ``` -------------------------------- ### Configure tsconfig.json for src Directory Source: https://docs.plasmo.com/framework/customization/src Manually update your tsconfig.json to resolve module paths starting with '~' to the './src' directory. This ensures TypeScript correctly locates your source files. ```json { "extends": "plasmo/templates/tsconfig.base", "exclude": ["node_modules"], "include": [".plasmo/index.d.ts", "./**/*.ts", "./**/*.tsx"], "compilerOptions": { "paths": { "~*": ["./src/*"] }, "baseUrl": "." } } ``` -------------------------------- ### Create Plasmo Extension with Specific Entry Files Source: https://docs.plasmo.com/framework/workflows/new Customize the initial project structure by specifying entry files using the `--entry` flag. Note the `--` escape for npm. Supports pnpm and npm. ```bash pnpm create plasmo --entry=options,newtab,contents/inline ``` ```bash npm create plasmo -- --entry=options,newtab,contents/inline ``` -------------------------------- ### Popup with SCSS Import in Plasmo Source: https://docs.plasmo.com/quickstarts/migrate-to-plasmo Plasmo supports direct SCSS imports within React components. This example shows how to import a SCSS file into your `popup.tsx` file for styling. ```tsx import Popup from "./core/popup" import "./popup.scss" export default Popup ``` -------------------------------- ### Importing GraphQL Files Source: https://docs.plasmo.com/framework/import GraphQL and gql files can be imported using the '~' prefix for project-relative paths. ```typescript import query from "~query.gql" ``` -------------------------------- ### Build for Specific Target Source: https://docs.plasmo.com/framework/workflows/build Specify a browser and manifest version combination for your build using the `--target` flag. This enables target-specific environment files and entry points. ```bash plasmo build --target=firefox-mv2 ``` -------------------------------- ### Use Experimental Plasmo Version Source: https://docs.plasmo.com/framework/workflows/faq To use the experimental version of Plasmo, set the 'plasmo' dependency version to 'lab' in your package.json file and then run your package manager's install command. ```json { "dependencies": { "plasmo": "lab" } } ``` -------------------------------- ### Get Port and Listen in Svelte Source: https://docs.plasmo.com/framework/messaging Obtain a port instance using `getPort` in a Svelte component to establish a connection with the background service worker. Listen for messages and send data through the port. ```svelte
{output}
``` -------------------------------- ### React Hook API - With Custom Storage Instance Source: https://docs.plasmo.com/framework/storage Demonstrates how to use the `useStorage` hook with a custom instance of `Storage` or `SecureStorage`. ```APIDOC ## React Hook API - With Custom Storage Instance ### Description This example shows how to provide a custom storage instance (e.g., configured with a specific area or encryption) to the `useStorage` hook. ### Method N/A ### Endpoint N/A ### Parameters #### `useStorage` Hook Parameters - **options** (object) - **key** (string) - The key of the storage item. - **instance** (Storage | SecureStorage) - An instance of Storage or SecureStorage to use. - **defaultValue** (any) - Optional - The default value if the key does not exist. ### Request Example ```javascript import { useStorage } from "@plasmohq/storage/hook" import { Storage } from "@plasmohq/storage" const localSt = new Storage({ area: "local" }) function MyComponent() { const [hailingFrequency] = useStorage({ key: "hailing", instance: localSt }) // ... } ``` ### Response N/A ``` -------------------------------- ### Manual Upload API - Step 3: Finalize Upload Source: https://docs.plasmo.com/itero/api Finalizes the upload process and updates the extension bundle to be served to beta testers. ```APIDOC ## POST /api/submit/sign ### Description Finalizes the extension upload process and updates the bundle for beta testers. ### Method POST ### Endpoint https://itero.plasmo.com/api/submit/sign ### Parameters #### Request Body - **keys.itero** (object) - Required - The `itero` object obtained from your downloaded API key JSON file. ### Request Example ```json { "itero": { "someKey": "someValue" } } ``` ### Response #### Success Response (200) - (No specific response fields mentioned, implies success confirmation) #### Response Example (No example provided in source text) ``` -------------------------------- ### React Hook for Firebase User Authentication Source: https://docs.plasmo.com/quickstarts/with-firebase-authentication Example of using the `useFirebaseUser` hook in a React component for authentication. This snippet shows how to conditionally render UI elements based on user authentication status. ```typescript // src/options.tsx import AuthForm from "~components/AuthForm" import "./style.css" import useFirebaseUser from "~firebase/useFirebaseUser" export default function Options() { const { user, isLoading, onLogin } = useFirebaseUser() return (
{!user && } {user &&
You're signed in! Woo
}
) } ``` -------------------------------- ### Create Plasmo Project with Tailwind CSS Source: https://docs.plasmo.com/quickstarts/with-tailwindcss Use this command to scaffold a new Plasmo project with Tailwind CSS pre-configured. ```bash pnpm create plasmo --with-tailwindcss ``` -------------------------------- ### Use Plasmo Storage Hooks in Options Page Source: https://docs.plasmo.com/quickstarts/with-chrome-storage This example demonstrates reading storage values in a React options page component using `useStorage` hooks. It retrieves 'open-count' and 'checked' states. ```typescript import { useStorage } from "@plasmohq/storage/hook" function IndexOptions() { const [openCount] = useStorage("open-count") const [checked] = useStorage("checked") return (

Times opened: {openCount}

) } export default IndexOptions ``` -------------------------------- ### Generate Production Zip Bundle Source: https://docs.plasmo.com/framework/workflows/build Use the `package` command to create a production zip bundle ready for upload to web stores. This command is available for both pnpm and npm. ```bash pnpm package # OR npm run package ``` -------------------------------- ### Get Multiple Overlay Anchors Function Source: https://docs.plasmo.com/framework/content-scripts-ui/life-cycle Export a `getOverlayAnchorList` function to specify multiple overlay anchor elements for mounting. Note: This does not currently support dynamic additions to the DOM after initial rendering. ```typescript import type { PlasmoGetOverlayAnchorList } from "plasmo" export const getOverlayAnchorList: PlasmoGetOverlayAnchorList = async () => document.querySelectorAll("a") ``` -------------------------------- ### Manual Upload API - Step 2: Upload Zip File Source: https://docs.plasmo.com/itero/api Upload your extension's zip file to the signed URL obtained in Step 1. ```APIDOC ## PUT [signed-upload-url] ### Description Uploads the extension's zip file to the provided signed URL. ### Method PUT ### Endpoint [signed-upload-url] (from Step 1 response) ### Parameters #### Request Body - **zip file** (blob) - Required - The zip archive of your extension. ### Headers - **Content-Type**: application/zip ``` -------------------------------- ### Use Plasmo Storage Hooks in Popup Source: https://docs.plasmo.com/quickstarts/with-chrome-storage This example shows how to use `useStorage` hooks to read and update storage values within a React popup component. It initializes 'open-count' to 0 if not found and manages a 'checked' state. ```typescript import { useStorage } from "@plasmohq/storage/hook" function IndexPopup() { const [openCount] = useStorage("open-count", (storedCount) => typeof storedCount === "undefined" ? 0 : storedCount + 1 ) const [checked, setChecked] = useStorage("checked", true) return (

Times opened: {openCount}

setChecked(e.target.checked)} />
) } export default IndexPopup ``` -------------------------------- ### Get Custom Root Container Source: https://docs.plasmo.com/framework/content-scripts-ui/life-cycle Replace Plasmo's default Shadow DOM container with a custom element by exporting a getRootContainer function. This is useful for scenarios where you need to mount the component directly into the webpage or use an iframe. ```typescript import type { PlasmoGetRootContainer } from "plasmo" export const getRootContainer = () => document.getElementById("itero") ``` -------------------------------- ### Build with Minification Disabled Source: https://docs.plasmo.com/framework/workflows/build Create a production bundle without minification by using the `--no-minify` flag. This can be useful during development or for specific optimization needs. ```bash plasmo build --no-minify ``` -------------------------------- ### Implement Google Analytics Tracking in React Component Source: https://docs.plasmo.com/quickstarts/with-google-analytics Integrate the Google Analytics gtag script into a React component's useEffect hook. This example initializes dataLayer, defines the gtag function, and configures the analytics with your Measurement ID and debug mode. ```typescript import "https://www.googletagmanager.com/gtag/js?id=$PLASMO_PUBLIC_GTAG_ID" import { useEffect, useState } from "react" function IndexPopup() { const [data, setData] = useState("") useEffect(() => { window.dataLayer = window.dataLayer || [] window.gtag = function gtag() { window.dataLayer.push(arguments) // eslint-disable-line } window.gtag("js", new Date()) window.gtag("config", process.env.PLASMO_PUBLIC_GTAG_ID, { page_path: "/popup", debug_mode: true }) window.gtag("event", "login", { method: "TEST" }) }, []) return (

Welcome to your Plasmo Extension!

setData(e.target.value)} value={data} />
) } export default IndexPopup ``` -------------------------------- ### Initialize Firebase Client Source: https://docs.plasmo.com/quickstarts/with-firebase-authentication Set up a singleton instance of the Firebase client application. This code initializes Firebase with credentials from environment variables and exports instances for auth, firestore, and storage. It prevents re-initialization on hot-reloads. ```typescript // src/firebase/firebaseClient.ts import { getApps, initializeApp } from "firebase/app" import { GoogleAuthProvider, getAuth } from "firebase/auth" import { getFirestore } from "firebase/firestore" import { getStorage } from "firebase/storage" const clientCredentials = { apiKey: process.env.PLASMO_PUBLIC_FIREBASE_PUBLIC_API_KEY, authDomain: process.env.PLASMO_PUBLIC_FIREBASE_AUTH_DOMAIN, projectId: process.env.PLASMO_PUBLIC_FIREBASE_PROJECT_ID, storageBucket: process.env.PLASMO_PUBLIC_FIREBASE_STORAGE_BUCKET, messagingSenderId: process.env.PLASMO_PUBLIC_FIREBASE_MESSAGING_SENDER_ID, appId: process.env.PLASMO_PUBLIC_FIREBASE_APP_ID, measurementId: process.env.PLASMO_PUBLIC_FIREBASE_MEASUREMENT_ID } let firebase_app // Check if firebase app is already initialized to avoid creating new app on hot-reloads if (!getApps().length) { firebase_app = initializeApp(clientCredentials) } else { firebase_app = getApps()[0] } export const storage = getStorage(firebase_app) export const auth = getAuth(firebase_app) export const db = getFirestore(firebase_app) export const googleAuth = new GoogleAuthProvider() export default firebase_app ``` -------------------------------- ### Generate Bundle Buddy Report Source: https://docs.plasmo.com/framework/workflows/build Combine `--source-maps` with the `--bundle-buddy` flag to generate an interactive Bundle Buddy report for analyzing your bundle's contents. ```bash plasmo build --source-maps --bundle-buddy ``` -------------------------------- ### PUT Signed URL Request Source: https://docs.plasmo.com/itero/api Use the signed URL obtained from the previous step to upload your extension's zip file. Ensure the Content-Type header is set to 'application/zip'. ```http PUT signed-upload-url Content-Type: application/zip [zip blob] ``` -------------------------------- ### Importing Bundled and Optimized Assets with URL Source: https://docs.plasmo.com/framework/import The 'url' scheme bundles, optimizes, and copies assets into the extension. It adds the file to 'web_accessible_resources' for content scripts and assigns a content hash. ```typescript import styleAUrl from "url:~/a/style.scss" import styleBUrl from "url:~/b/style.scss" import codeUrl from "url:~/c/index.ts" console.log(styleAUrl) // chrome-extension:///style..css console.log(styleBUrl) // chrome-extension:///style..css console.log(codeUrl) // chrome-extension:///file..js ``` -------------------------------- ### React Hook API - Basic Usage Source: https://docs.plasmo.com/framework/storage Shows how to use the `useStorage` hook to easily manage and synchronize state within React components. ```APIDOC ## React Hook API - Basic Usage ### Description The `useStorage` hook simplifies state synchronization in React components. It automatically watches for changes and re-renders the component when the stored value updates. ### Method N/A ### Endpoint N/A ### Parameters #### `useStorage` Hook Parameters - **key** (string) - The key of the storage item to use. - **defaultValue** (any) - Optional - The default value to use if the key does not exist. ### Request Example ```javascript import { useStorage } from "@plasmohq/storage/hook" function MyComponent() { const [hailingFrequency] = useStorage("hailing") // ... return (
{hailingFrequency}
) } ``` ### Response N/A ``` -------------------------------- ### Supabase Environment Variables Source: https://docs.plasmo.com/quickstarts/with-supabase Define your Supabase URL and Key in the .env file. Ensure these are kept private and not committed to version control. ```dotenv PLASMO_PUBLIC_SUPABASE_URL="CHANGE ME" PLASMO_PUBLIC_SUPABASE_KEY="CHANGE ME" ``` -------------------------------- ### POST Sign Endpoint Request Source: https://docs.plasmo.com/itero/api After uploading the zip file, call this POST request to finalize the process and update the extension bundle for beta testers. Include the 'keys.itero' object in the request body. ```javascript const keys = JSON.parse(await readFile("./keys.json", "utf8")) // with keys.json being the file you downloaded from the settings page ... const resp = await fetch("https://itero.plasmo.com/api/submit/sign", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(keys.itero) }) const data = await resp.json() console.log(data) ``` -------------------------------- ### Create User Info React Context Provider Source: https://docs.plasmo.com/quickstarts/with-stripe This code sets up a React context provider using puro to fetch and cache user profile information. It uses useEffect to call chrome.identity.getProfileUserInfo and stores the data in state. ```typescript import { createProvider } from "puro" import { useContext, useEffect, useState } from "react" const useUserInfoProvider = () => { const [userInfo, setUserInfo] = useState(null) useEffect(() => { chrome.identity.getProfileUserInfo((data) => { if (data.email && data.id) { setUserInfo(data) } }) }, []) return userInfo } const { BaseContext, Provider } = createProvider(useUserInfoProvider) export const useUserInfo = () => useContext(BaseContext) export const UserInfoProvider = Provider ``` -------------------------------- ### Configure Redux Store with Persistence Source: https://docs.plasmo.com/quickstarts/with-redux Set up the Redux store using Redux Toolkit, integrating redux-persist for state persistence with chrome.storage. Includes middleware configuration and a watcher for store synchronization. ```typescript import { configureStore } from "@reduxjs/toolkit" import { localStorage } from "redux-persist-webextension-storage" import { FLUSH, PAUSE, PERSIST, PURGE, REGISTER, REHYDRATE, RESYNC, persistReducer, persistStore } from "@plasmohq/redux-persist" import { Storage } from "@plasmohq/storage" import counterSlice from "~counter-slice" const rootReducer = counterSlice const persistConfig = { key: "root", version: 1, storage: localStorage } const persistedReducer = persistReducer(persistConfig, rootReducer) export const store = configureStore({ reducer: persistedReducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: { ignoredActions: [ FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER, RESYNC ] } }) }) export const persistor = persistStore(store) // This is what makes Redux sync properly with multiple pages // Open your extension's options page and popup to see it in action new Storage().watch({ [`persist:${persistConfig.key}`]: () => { persistor.resync() } }) ``` -------------------------------- ### Storage API - Copying to localStorage Source: https://docs.plasmo.com/framework/storage Explains how to configure the Storage API to automatically copy specified data to the browser's localStorage. ```APIDOC ## Storage API - Copying to localStorage ### Description This configuration allows data to be automatically copied to the browser's localStorage, which can be useful for content scripts or extension pages. ### Method N/A ### Endpoint N/A ### Parameters #### Initialization Options - **copiedKeyList** (string[]) - Optional - A list of keys whose values should be copied to localStorage. ### Request Example ```javascript import { Storage } from "@plasmohq/storage" const storage = new Storage({ copiedKeyList: ["shield-modulation"] }) ``` ### Response N/A ``` -------------------------------- ### Reference Locale Strings in package.json Source: https://docs.plasmo.com/framework/locales Use the __MSG___ syntax to reference localized strings directly within your package.json for fields like 'name', 'displayName', and 'description'. This allows for localized metadata. ```json { "name": "with-locales-i18n", "displayName": "__MSG_extensionName__", "version": "0.0.0", "description": "__MSG_extensionDescription__", "manifest": { "name": "__MSG_extensionName__" } } ``` -------------------------------- ### Mount and Interact with Sandbox Page Source: https://docs.plasmo.com/framework/sandbox-pages Mount a sandbox page in an iframe and use `postMessage` to send code for evaluation. Results are logged to the console. ```typescript import { useEffect, useRef, useState } from "react" function IndexPopup() { const iframeRef = useRef(null) useEffect(() => { window.addEventListener("message", (event) => { console.log("EVAL output: " + event.data) }) }, []) return (