Step 1: Getting Started with Widget Development
Welcome to widget development! In this step, youβll set up your development environment and get familiar with the widget development workflow.
π― What Youβll Accomplish
By the end of this step, youβll have:
- Development environment ready - All prerequisites installed and configured
- Widget starter kit cloned - Your own copy of the widget template
- Development server running - Local widget development environment active
- Project structure understanding - Know how widget projects are organized
π’ Check With Your Organization First
Before diving into the standard tools, check with your platform team to see if your organization provides:
- Custom widget starter kit - Organization-specific template with company standards
- Internal development guidelines - Company-specific setup instructions
- Custom development tools - Organization-specific CLI tools or workflows
- Internal widget registry - Private package registry for dependencies
If your organization has custom tools, use those instead! The concepts in this tutorial will still apply.
π§ Prerequisites Check
Ensure you have the following installed:
Node.js and Package Manager
# Check Node.js version (22+ required)node --version
# Check yarn version(4.x.x)yarn --version
π¦ Cloning the Widget Starter Kit
Weβre going to clone the widget starter kit to begin developing your first widget.
Wait, whatβs a widget? π€ Itβs a self-contained piece of JavaScript that runs in the 1fe ecosystem - like a mini-app! And the starter kit is your pre-configured template with all the tooling you need.
1. Clone the Repository
# Clone the widget starter kitgit clone https://github.com/docusign/1fe-widget-starter-kit.git my-first-widget
# Navigate to the projectcd my-first-widget
2. Install Dependencies
# Install all dependenciesyarn install
This will install all the necessary dependencies for widget development
3. Explore the Project Structure
Letβs understand what you just cloned:
my-first-widget/βββ src/ # Your widget source codeβ βββ components/ # Reusable React componentsβ βββ contract.ts # Widget contract definitionβ βββ app1.tsx # Main widget entry pointβ βββ widget.ts # Default widget exportβββ tests/ # Test filesβββ .1fe.config.ts # Widget build and runtime configurationβββ package.json # Dependencies and scriptsβββ README.md # Project documentation
ποΈ Understanding Key Files
Widget Entry Point (src/app1.tsx
)
This is your main widget component:
import { platformProps } from "@1fe/shell";import React, { useEffect } from "react";import { Router as Widget } from "./components/router";import { withProvider } from "./withProvider";import { WidgetProps } from "./contract";
const RootWrapper: React.FC<WidgetProps> = (props) => { useEffect(() => { platformProps.utils.appLoadTime.end(); console.log("props", props); }, []);
return <Widget {...props} />;};
export default withProvider(RootWrapper);
Notice that platformProps
in there? Thatβs your widgetβs toolkit - built-in utilities for things like app load time tracking, context management, event communication, and more! π§° Discover all the cool utilities you get for free.
Widget Contract (src/contract.ts
)
This is your widget contract - it defines what data your widget expects to receive and what it promises to provide. Think of it as the βhandshakeβ between your widget and the platform. Curious about how contracts work? π€
import { PlatformPropsType } from "@1fe/shell";
export type HostPropsContract = Record<string, unknown>;
export type WidgetProps = { host: HostPropsContract; platform: PlatformPropsType;};
Configuration (.1fe.config.ts
)
This little file is actually quite powerful - it controls how your widget is built, bundled, and deployed! It tells the 1fe CLI how to process your widget and what dependencies it needs. Want to know what else it can do? βοΈ
import { OneFeConfiguration } from "@1fe/cli";import { getBaseConfig } from "@1fe/sample-widget-base-config"; // this is the redistributed package for the organization
const configuration: OneFeConfiguration = { baseConfig: getBaseConfig,};
export default configuration;
π Starting the Development Server
Now letβs get your widget running locally:
# Start the development serveryarn dev
You should see output similar to:
β Webpack Compiled successfully in 3.82s
<i> [webpack-dev-server] Project is running at:<i> [webpack-dev-server] Loopback: http://127.0.0.1:8080/<i> [webpack-dev-server] 404s will fallback to '/index.html'post action hook executed[dev] Opening the widget in the playground with the URL: http://localhost:3001/playground?widgetUrl=http%3A%2F%2F127.0.0.1%3A8080%2Fjs%2F1fe-bundle.js
And there it is - your widget will open in the 1fe Playground! The playground is a development sandbox that provides an isolated environment for testing widgets without needing the full application setup. Think of it as your widgetβs sandbox where it can play safely. Want to explore what the playground can do? π
What just happened?
- The 1fe CLI compiled your widget
- Started a local development server
- Made your widget available at a local URL
- Enabled hot reloading for development
π Verifying Your Setup
Letβs make sure everything is working:
1. Check the Bundle URL
Open your browser and visit:
http://localhost:8080/js/1fe-bundle.js
You should see JavaScript code (the compiled widget bundle).
2. Open in playground
If your team doesnβt have their own 1fe instance, you can open the widget in our demo 1fe instances playground by visiting:
http://demo.1fe.com/playground?widgetUrl=http%3A%2F%2F127.0.0.1%3A8080%2Fjs%2F1fe-bundle.js
3. Make a Test Change
Edit src/app1.tsx
and change the heading:
import { platformProps } from "@1fe/shell";import React, { useEffect } from "react";import { Alert } from "antd";import { Router as Widget } from "./components/router";import { withProvider } from "./withProvider";import { WidgetProps } from "./contract";
const RootWrapper: React.FC<WidgetProps> = (props) => { useEffect(() => { platformProps.utils.appLoadTime.end(); console.log("Widget loaded with props:", props); }, [props]);
return ( <div> <Alert message="π Widget Ready!" type="success" style={{ margin: "8px" }} closable /> <Widget {...props} /> </div> );};
export default withProvider(RootWrapper);
Save the file and watch your terminal - you should see the widget recompile automatically and your browser should show a pretty banner at the top of the page with a close button.
π Understanding Widget Architecture
Platform Integration
Your widget runs within the 1fe platform and has access to:
- Platform utilities - Shared functions for logging, navigation, etc.
- Shared dependencies - React, design systems, and common libraries
- Shell context - Platform-wide state and configuration
- Event system - Communication with other widgets and the shell
Development Workflow
The typical development cycle is:
- Code - Write widget functionality in
src/
- Test - Use the playground for immediate feedback
- Build - Compile with
yarn build:widget
- Deploy - Push to your organizationβs deployment pipeline
π Success!
Congratulations! You now have a fully functional widget development environment. Your widget is compiled, served locally, and ready for development.
π Next Step
Now that your development environment is ready, letβs learn how to use the 1fe Playground to develop and test your widget interactively.
β Step 2: Learn about the Playground
In the next step, we will explore the playground to learn more of itβs features.