From e2692dda9c0e06beb2134d621820aed3c30dd6d7 Mon Sep 17 00:00:00 2001 From: Mohit Khatri Date: Fri, 22 Aug 2025 11:23:10 -0700 Subject: [PATCH 1/3] Doc updates --- astro.config.mjs | 16 + config-utils/sidebar.ts | 11 - public/custom-sidebar-behavior.js | 138 +++++ public/custom-sidebar.css | 41 ++ public/favicon.svg | 4 +- .../getting-started.mdx | 293 ---------- .../Developing Your First Widget/index.mdx | 154 ----- .../cdn-setup.mdx | 43 -- .../ci-cd-pipeline.mdx | 63 -- .../configuration-service.mdx | 42 -- .../hosting-setup.mdx | 43 -- .../Productionize your 1fe instance/index.mdx | 147 ----- .../npm-registry.mdx | 44 -- .../Setup and Deploy 1fe POC/deploy-poc.mdx | 222 ------- .../develop-locally.mdx | 307 ---------- .../Setup and Deploy 1fe POC/index.mdx | 89 --- .../Setup and Deploy 1fe POC/installation.mdx | 90 --- .../assets/example-child-widget.png | Bin .../assets/example-plugin-cdn-assets.png | Bin .../assets/example-plugin-change.png | Bin .../assets/example-plugin-dist.png | Bin .../assets/import-map-shelf.png | Bin .../assets/override-modal.png | Bin .../assets/three-dots.png | Bin .../developing-your-first-widget.mdx | 549 ++++++++++++++++++ src/content/docs/tutorials/index.mdx | 32 +- .../productionize-your-1fe-instance.mdx | 449 ++++++++++++++ .../tutorials/setup-and-deploy-1fe-poc.mdx | 443 ++++++++++++++ src/custom-sidebar-behavior.js | 51 ++ src/styles/custom-sidebar.css | 32 + 30 files changed, 1732 insertions(+), 1571 deletions(-) create mode 100644 public/custom-sidebar-behavior.js create mode 100644 public/custom-sidebar.css delete mode 100644 src/content/docs/tutorials/Developing Your First Widget/getting-started.mdx delete mode 100644 src/content/docs/tutorials/Developing Your First Widget/index.mdx delete mode 100644 src/content/docs/tutorials/Productionize your 1fe instance/cdn-setup.mdx delete mode 100644 src/content/docs/tutorials/Productionize your 1fe instance/ci-cd-pipeline.mdx delete mode 100644 src/content/docs/tutorials/Productionize your 1fe instance/configuration-service.mdx delete mode 100644 src/content/docs/tutorials/Productionize your 1fe instance/hosting-setup.mdx delete mode 100644 src/content/docs/tutorials/Productionize your 1fe instance/index.mdx delete mode 100644 src/content/docs/tutorials/Productionize your 1fe instance/npm-registry.mdx delete mode 100644 src/content/docs/tutorials/Setup and Deploy 1fe POC/deploy-poc.mdx delete mode 100644 src/content/docs/tutorials/Setup and Deploy 1fe POC/develop-locally.mdx delete mode 100644 src/content/docs/tutorials/Setup and Deploy 1fe POC/index.mdx delete mode 100644 src/content/docs/tutorials/Setup and Deploy 1fe POC/installation.mdx rename src/content/docs/tutorials/{Setup and Deploy 1fe POC => }/assets/example-child-widget.png (100%) rename src/content/docs/tutorials/{Setup and Deploy 1fe POC => }/assets/example-plugin-cdn-assets.png (100%) rename src/content/docs/tutorials/{Setup and Deploy 1fe POC => }/assets/example-plugin-change.png (100%) rename src/content/docs/tutorials/{Setup and Deploy 1fe POC => }/assets/example-plugin-dist.png (100%) rename src/content/docs/tutorials/{Setup and Deploy 1fe POC => }/assets/import-map-shelf.png (100%) rename src/content/docs/tutorials/{Setup and Deploy 1fe POC => }/assets/override-modal.png (100%) rename src/content/docs/tutorials/{Setup and Deploy 1fe POC => }/assets/three-dots.png (100%) create mode 100644 src/content/docs/tutorials/developing-your-first-widget.mdx create mode 100644 src/content/docs/tutorials/productionize-your-1fe-instance.mdx create mode 100644 src/content/docs/tutorials/setup-and-deploy-1fe-poc.mdx create mode 100644 src/custom-sidebar-behavior.js create mode 100644 src/styles/custom-sidebar.css diff --git a/astro.config.mjs b/astro.config.mjs index 1813eac..3e83ff2 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -30,6 +30,22 @@ export default defineConfig({ }, sidebar: sidebarConfig, disable404Route: true, + head: [ + { + tag: "script", + attrs: { + src: "/custom-sidebar-behavior.js", + defer: true, + }, + }, + { + tag: "link", + attrs: { + rel: "stylesheet", + href: "/custom-sidebar.css", + }, + }, + ], expressiveCode: { // You can optionally override the plugin's default settings here frames: {}, diff --git a/config-utils/sidebar.ts b/config-utils/sidebar.ts index c970dec..3064a34 100644 --- a/config-utils/sidebar.ts +++ b/config-utils/sidebar.ts @@ -3,36 +3,25 @@ export const sidebarConfig = [ label: "Start Here", autogenerate: { directory: "start-here" }, collapsed: true, - // attrs: { style: "text-transform: 'capitalized'" }, }, { label: "Tutorials", autogenerate: { directory: "tutorials" }, collapsed: true, - // attrs: { style: "text-transform: 'capitalized'" }, }, { label: "Learning", autogenerate: { directory: "learning" }, collapsed: true, - // attrs: { style: "text-transform: 'capitalized'" }, }, { label: "How-to Guides", autogenerate: { directory: "how-to-guides" }, collapsed: true, - // attrs: { style: "text-transform: 'capitalized'" }, }, { label: "Reference", autogenerate: { directory: "reference" }, collapsed: true, - // attrs: { style: "text-transform: 'capitalized'" }, }, - // { - // label: 'Explanation', - // autogenerate: { directory: 'explanation' }, - // collapsed: true, - // // attrs: { style: "text-transform: 'capitalized'" }, - // } ]; diff --git a/public/custom-sidebar-behavior.js b/public/custom-sidebar-behavior.js new file mode 100644 index 0000000..0acee64 --- /dev/null +++ b/public/custom-sidebar-behavior.js @@ -0,0 +1,138 @@ +// Custom sidebar behavior for Starlight +// Adds auto-focus to index pages when opening folders + +(function () { + "use strict"; + + let isInitialized = false; + let processingClick = false; // Prevent infinite loops + + function initCustomSidebarBehavior() { + if (isInitialized) return; + + // Try multiple selectors to find the sidebar + const sidebar = + document.querySelector(".sidebar-content") || + document.querySelector("[data-sidebar]") || + document.querySelector(".sidebar") || + document.querySelector("nav[aria-label*='Sidebar']") || + document.querySelector("aside"); + + if (!sidebar) { + console.log("Sidebar not found, retrying..."); + // Only retry a few times to prevent infinite retries + setTimeout(initCustomSidebarBehavior, 500); + return; + } + + // Find all collapsible groups (folders) in the sidebar + let groups = sidebar.querySelectorAll("details"); + + // If no details found, try looking in the entire document + if (groups.length === 0) { + groups = document.querySelectorAll("details"); + } + + if (groups.length === 0) { + console.log("No collapsible groups found"); + return; + } + + console.log(`Found ${groups.length} sidebar groups`); + + groups.forEach((group, index) => { + const summary = group.querySelector("summary"); + if (!summary) return; + + // Add click listener without cloning (which was causing issues) + summary.addEventListener("click", function (e) { + if (processingClick) return; // Prevent infinite loops + + const isCurrentlyOpen = group.hasAttribute("open"); + console.log( + `Clicked group ${index}, currently open: ${isCurrentlyOpen}` + ); + + // If clicking to open this group + if (!isCurrentlyOpen) { + processingClick = true; + + // Auto-navigate to index page immediately + const links = group.querySelectorAll("a[href]"); + let indexLink = null; + + // Try to find index page + for (const link of links) { + const href = link.getAttribute("href"); + if ( + href && + (href.endsWith("/") || + href.includes("/index") || + href.split("/").pop() === "") + ) { + indexLink = link; + break; + } + } + + // If no specific index found, use the first link + if (!indexLink && links.length > 0) { + indexLink = links[0]; + } + + if (indexLink) { + const targetHref = indexLink.getAttribute("href"); + console.log(`Auto-navigating to: ${targetHref}`); + + // Check if we're not already on this page + if (window.location.pathname !== targetHref) { + window.location.href = targetHref; + } + } + + processingClick = false; + } else { + processingClick = false; + } + }); + }); + + isInitialized = true; + console.log("Custom sidebar behavior initialized successfully"); + } + + // Simple initialization + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", function () { + setTimeout(initCustomSidebarBehavior, 100); + }); + } else { + setTimeout(initCustomSidebarBehavior, 100); + } + + // Re-initialize on page changes (but with protection against loops) + document.addEventListener("astro:page-load", function () { + isInitialized = false; + processingClick = false; + setTimeout(initCustomSidebarBehavior, 200); + }); + + // Debug function + window.debugSidebar = function () { + const sidebar = + document.querySelector(".sidebar-content") || + document.querySelector("aside"); + const groups = document.querySelectorAll("details"); + console.log("Sidebar debug:"); + console.log("Sidebar element:", sidebar); + console.log("Found groups:", groups.length); + groups.forEach((group, i) => { + console.log( + `Group ${i}:`, + group.querySelector("summary")?.textContent, + "Open:", + group.hasAttribute("open") + ); + }); + }; +})(); diff --git a/public/custom-sidebar.css b/public/custom-sidebar.css new file mode 100644 index 0000000..b83c555 --- /dev/null +++ b/public/custom-sidebar.css @@ -0,0 +1,41 @@ +/* Custom sidebar styles for improved accordion behavior */ + +/* Smooth transitions for sidebar groups */ +.sidebar-content details, +aside details { + transition: all 0.2s ease-in-out; +} + +/* Improved visual feedback for collapsible groups */ +.sidebar-content details[open] > summary, +aside details[open] > summary { + font-weight: 600; +} + +/* Smooth animation for group content */ +.sidebar-content details > div, +aside details > div { + transition: all 0.15s ease-in-out; +} + +/* Visual indication of active/focused group */ +.sidebar-content details:focus-within > summary, +aside details:focus-within > summary { + background-color: var(--sl-color-accent-low); + border-radius: 4px; +} + +/* Visual feedback for open groups */ +.sidebar-content details[open] > summary, +aside details[open] > summary { + font-weight: 600; +} + +/* Debug styles - remove these in production */ +.debug-sidebar details { + border: 1px solid red !important; +} + +.debug-sidebar details[open] { + border-color: green !important; +} diff --git a/public/favicon.svg b/public/favicon.svg index 9560f0c..49a4522 100644 --- a/public/favicon.svg +++ b/public/favicon.svg @@ -1,4 +1,4 @@ - + @@ -17,4 +17,4 @@ - + \ No newline at end of file diff --git a/src/content/docs/tutorials/Developing Your First Widget/getting-started.mdx b/src/content/docs/tutorials/Developing Your First Widget/getting-started.mdx deleted file mode 100644 index f7a146a..0000000 --- a/src/content/docs/tutorials/Developing Your First Widget/getting-started.mdx +++ /dev/null @@ -1,293 +0,0 @@ ---- -title: "Step 1: Getting Started with Widget Development" -description: Set up your development environment and understand the widget development workflow -sidebar: - order: 1 ---- - -import { - SlTarget, - SlCheck, - SlArrowRight, - SlWrench, - SlSettings, - SlFolder, -} from "react-icons/sl"; - -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 - -```bash -# 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](/learning/widgets/)**? 🤔 It's a self-contained piece of JavaScript that runs in the 1fe ecosystem - like a mini-app! And the **[starter kit](https://github.com/docusign/1fe-widget-starter-kit)** is your pre-configured template with all the tooling you need. - -### 1. Clone the Repository - -```bash -# Clone the widget starter kit -git clone https://github.com/docusign/1fe-widget-starter-kit.git my-first-widget - -# Navigate to the project -cd my-first-widget -``` - -### 2. Install Dependencies - -```bash -# Install all dependencies -yarn 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: - -```typescript title="src/app1.tsx" -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 = (props) => { - useEffect(() => { - platformProps.utils.appLoadTime.end(); - console.log("props", props); - }, []); - - return ; -}; - -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](/reference/platform-utilities/overview/)** 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](/learning/widgets/#contracts)**? 🤝 - -```typescript title="src/contract.ts" -import { PlatformPropsType } from "@1fe/shell"; - -export type HostPropsContract = Record; - -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](/reference/1fe-config-reference/)**? ⚙️ - -```typescript title=".1fe.config.ts" -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 - -:::note[1fe Instance Required] -**Important:** This command needs a running **1fe instance** to work. A 1fe instance is your deployed ecosystem - the shell application that hosts and orchestrates widgets. Don't have one yet? No worries! Check out **[what a 1fe instance is](/learning/what-is-1fe/)** 🏗️ and then follow [Tutorial 1: Setup and Deploy a 1fe POC](/tutorials/setup-and-deploy-1fe-poc/) to get your instance up and running locally. -::: - -Now let's get your widget running locally: - -```bash -# Start the development server -yarn dev -``` - -You should see output similar to: - -``` -✔ Webpack - Compiled successfully in 3.82s - - [webpack-dev-server] Project is running at: - [webpack-dev-server] Loopback: http://127.0.0.1:8080/ - [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](/learning/playground/)**? 🛝 - -**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: - -```typescript title="src/app1.tsx" {3, 16-21} -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 = (props) => { - useEffect(() => { - platformProps.utils.appLoadTime.end(); - console.log("Widget loaded with props:", props); - }, [props]); - - return ( -
- - -
- ); -}; - -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: - -1. **Code** - Write widget functionality in `src/` -2. **Test** - Use the playground for immediate feedback -3. **Build** - Compile with `yarn build:widget` -4. **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: Using the Playground for Development](/tutorials/developing-your-first-widget/using-playground/)** - -In the next step, we will explore the playground to learn more of it's features. - ---- diff --git a/src/content/docs/tutorials/Developing Your First Widget/index.mdx b/src/content/docs/tutorials/Developing Your First Widget/index.mdx deleted file mode 100644 index 875c9b8..0000000 --- a/src/content/docs/tutorials/Developing Your First Widget/index.mdx +++ /dev/null @@ -1,154 +0,0 @@ ---- -title: "Developing Your First Widget" -description: Complete guide for frontend developers to create, develop, and deploy widgets in an existing 1fe ecosystem -sidebar: - order: 0 ---- - -import { - FcEngineering, - FcSettings, - FcOrganization, - FcGraduationCap, -} from "react-icons/fc"; -import { SlTarget, SlUser, SlClock, SlCheck } from "react-icons/sl"; - -## 🎯 Overview - -This tutorial is designed for **frontend developers** working in organizations that already have a 1fe instance set up. You'll learn the complete widget development workflow, from initial setup to deployment preparation, using both standard 1fe tools and organization-specific implementations. - -## 👥 Who This Tutorial Is For - -**Frontend Developers** who need to: - -
- -- Build widgets for an existing 1fe ecosystem -- Understand the widget development workflow -- Learn to use development tools like the Playground -- Configure and customize widget behavior -- Prepare widgets for deployment - -
- -## 🏢 Important: Check With Your Organization First - -Before starting, **always check with your platform team or organization admin**. Your organization may have: - -
- -- **Custom Widget Starter Kits** - Organization-specific templates with company standards -- **Custom Playground Instances** - Internal development environments -- **Specific Development Guidelines** - Company-specific workflows and requirements -- **Custom CI/CD Pipelines** - Organization deployment processes - -
- -:::tip[Organization Tools First] -**Follow your organization's instructions first!** This tutorial uses the standard out-of-the-box 1fe tools to help you understand the fundamentals. Once you understand these concepts, you can easily adapt to your organization's custom tools. -::: - -## ⚡ What You'll Build - -By completing this tutorial, you'll create a fully functional widget and understand: - -
- -- **Widget development environment** - Set up and configure your development workspace -- **Playground-driven development** - Use the playground for rapid iteration and testing -- **Widget configuration** - Understand and customize widget behavior through configuration -- **Build and deployment** - Prepare your widget for deployment - -
- -## 📚 Tutorial Steps - -### 🚀 Step 1: Getting Started with Widget Development - -Set up your development environment by cloning the widget starter kit, installing dependencies, and understanding the project structure. - -**→ [Start with Step 1: Getting Started](/tutorials/developing-your-first-widget/getting-started/)** - -### 🛝 Step 2: Using the Playground for Development - -Learn to use the 1fe Playground as your primary development environment for testing and iterating on widgets. - -**→ [Continue to Step 2: Using the Playground](/tutorials/developing-your-first-widget/using-playground/)** - -### ⚙️ Step 3: Understanding Widget Configuration - -Deep dive into widget configuration, contracts, and how widgets integrate with the 1fe platform. - -**→ [Continue to Step 3: Widget Configuration](/tutorials/developing-your-first-widget/widget-configuration/)** - -### 🏗️ Step 4: Building and Testing Your Widget - -Learn the complete build process, testing strategies, and how to prepare your widget for deployment. - -**→ [Complete with Step 4: Building and Testing](/tutorials/developing-your-first-widget/building-testing/)** - -## 🔗 Prerequisites - -Before starting this tutorial, ensure you have: - -
- -- **Node.js 22+** - Required for widget development -- **yarn** - Package manager for dependencies -- **Code editor** - VS Code or your preferred editor -- **Access to 1fe instance** - Your organization's 1fe instance or demo.1fe.com -- **Basic React knowledge** - Widgets are built using React - -
- -## 🎯 Learning Objectives - -After completing this tutorial, you'll be able to: - -**✅ Development Setup:** - -- Set up a complete widget development environment -- Understand widget project structure and tooling - -**✅ Development Workflow:** - -- Use the playground for rapid development and testing -- Implement real-time development with hot reloading - -**✅ Widget Configuration:** - -- Configure widgets using .1fe.config.ts -- Understand widget contracts and platform integration - -**✅ Production Readiness:** - -- Build and validate widgets for deployment -- Understand the deployment workflow -- Know how to integrate with organization CI/CD processes - -## 👉 Ready to Start? - -Widget development in 1fe is designed to be intuitive and powerful. Let's dive in and build your first widget! - -**→ [Step 1: Getting Started with Widget Development](/tutorials/developing-your-first-widget/getting-started/)** - ---- - -## 🤝 Need Help? - -The 1fe community is here to support your widget development journey: - -
- -- **💬 Join Discussions** - Ask questions and share knowledge in our [Community Discussions](https://github.com/docusign/1fe/discussions) -- **🐛 Report Issues** - Found a bug or problem? [Create an issue](https://github.com/docusign/1fe/issues) -- **📚 Explore Docs** - Check our [How-to Guides](/how-to-guides/) and [Reference](/reference/) sections -- **❓ Browse FAQs** - Visit our [Frequently Asked Questions](/learning/faqs/) - -
- ---- - -:::tip[Developer Success] -Remember: this tutorial teaches you the fundamentals using standard tools. These concepts apply directly to any organization-specific implementations your company may have. The workflow and concepts remain consistent! -::: diff --git a/src/content/docs/tutorials/Productionize your 1fe instance/cdn-setup.mdx b/src/content/docs/tutorials/Productionize your 1fe instance/cdn-setup.mdx deleted file mode 100644 index 22f368d..0000000 --- a/src/content/docs/tutorials/Productionize your 1fe instance/cdn-setup.mdx +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "Step 2: Setup CDN for Widget Bundles" -description: Configure content delivery network for widget bundles -sidebar: - order: 2 ---- - -import { FaCloud, FaArrowRight } from "react-icons/fa"; - -You need a Content Delivery Network (CDN) to efficiently deliver your widget bundles to users worldwide with fast loading times and global caching. - -## 🎯 What You'll Set Up - -
- -- **Global CDN infrastructure** for widget bundle delivery -- **Caching policies** and compression settings -- **SSL/TLS security** for content delivery -- **Cache invalidation** for deploying updates - -
- -## 📖 Complete Setup Guide - -Follow our detailed step-by-step guide for CDN setup: - -**[→ CDN Setup Guide](/how-to-guides/infrastructure-setup/cdn-setup/)** - -## ✅ Verification - -After completing the setup, verify: - -
- -- Widget bundles load from CDN endpoints -- Cache invalidation works for deployments -- SSL certificates are valid for CDN endpoints - -
- -## 🚀 Next Step - -** [Step 3: Setup NPM Registry](/tutorials/productionize-your-1fe-instance/npm-registry/)** diff --git a/src/content/docs/tutorials/Productionize your 1fe instance/ci-cd-pipeline.mdx b/src/content/docs/tutorials/Productionize your 1fe instance/ci-cd-pipeline.mdx deleted file mode 100644 index 5d3209e..0000000 --- a/src/content/docs/tutorials/Productionize your 1fe instance/ci-cd-pipeline.mdx +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: "Step 5: Setup CI/CD Pipeline" -description: Configure automated deployment workflows for your 1fe instance -sidebar: - order: 5 ---- - -import { FaGithub, FaCheckCircle } from "react-icons/fa"; - -1fe uses a centralized CI/CD system to manage deployments across all widgets with automated testing, building, and deployment processes. - -## 🎯 What You'll Set Up - -
- -- **Automated build pipelines** for your 1fe instance and widgets -- **Multi-environment deployment** with approval workflows -- **Automated rollback capabilities** for quick issue resolution - -
- -## 📖 Complete Setup Guide - -Follow our detailed step-by-step guide for CI/CD pipeline setup: - -**[→ CI/CD Pipeline Setup Guide](/how-to-guides/infrastructure-setup/project-setup/)** - -## ✅ Verification - -After completing the setup, verify: - -
- -- Automated builds trigger correctly on code changes -- Multi-environment deployment works with approval gates -- Rollback procedures can quickly revert deployments - -
- -## 🎉 Congratulations! - -You've successfully completed the productionization of your 1fe instance! Your organization now has: - -
- -- **Enterprise-grade infrastructure** supporting scalable micro-frontend development -- **Automated processes** reducing manual effort and deployment risks - -
- -## 🚀 Next Steps - -With your production infrastructure in place, you're ready to: - -
- -- Scale widget development across multiple teams -- Onboard additional developers using your established processes -- Monitor and optimize your production performance - -
- -**Welcome to production-grade 1fe instance!** 🎊 diff --git a/src/content/docs/tutorials/Productionize your 1fe instance/configuration-service.mdx b/src/content/docs/tutorials/Productionize your 1fe instance/configuration-service.mdx deleted file mode 100644 index 91b0628..0000000 --- a/src/content/docs/tutorials/Productionize your 1fe instance/configuration-service.mdx +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: "Step 4: Setup Configuration Service" -description: Configure dynamic settings management for your 1fe instance -sidebar: - order: 4 ---- - -import { FaDatabase, FaArrowRight } from "react-icons/fa"; - -1fe requires a configuration service to manage **widget metadata** including version information, deployment status, and dependencies without code changes. - -## 🎯 What You'll Set Up - -
- -- **Configuration service** (Azure App Configuration, AWS Parameter Store, etc.) -- **Environment-specific configurations** for different deployment stages - -
- -## 📖 Complete Setup Guide - -Follow our detailed step-by-step guide for configuration service setup: - -**[→ Configuration Service Setup Guide](/how-to-guides/infrastructure-setup/configuration-setup/)** - -## ✅ Verification - -After completing the setup, verify: - -
- -- Configuration retrieval works from your 1fe instance -- Environment separation functions correctly -- Security controls prevent unauthorized access -- Real-time updates propagate to running instances - -
- -## 🚀 Next Step - -** [Step 5: Setup CI/CD Pipeline](/tutorials/productionize-your-1fe-instance/ci-cd-pipeline/)** diff --git a/src/content/docs/tutorials/Productionize your 1fe instance/hosting-setup.mdx b/src/content/docs/tutorials/Productionize your 1fe instance/hosting-setup.mdx deleted file mode 100644 index 99c6f05..0000000 --- a/src/content/docs/tutorials/Productionize your 1fe instance/hosting-setup.mdx +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: "Step 1: Setup a Hosting Service" -description: Configure production hosting for your 1fe instance -sidebar: - order: 1 ---- - -import { FaMicrosoft, FaArrowRight } from "react-icons/fa"; - -Your 1fe application shell needs to be hosted on a reliable service that can handle user traffic and serve your application globally. - -## 🎯 What You'll Set Up - -
- -- **Production hosting service** (Azure Web App, AWS, etc.) -- **Environment variables** for production configuration -- **SSL/TLS security** and monitoring - -
- -## 📖 Complete Setup Guide - -Follow our detailed step-by-step guide for hosting setup: - -**[→ Hosting Service Setup Guide](/how-to-guides/infrastructure-setup/hosting-setup/)** - -## ✅ Verification - -After completing the setup, verify: - -
- -- Your 1fe instance loads from the production URL -- SSL certificate is properly configured -- Environment variables are accessible -- Monitoring is collecting logs and metrics - -
- -## 🚀 Next Step - -** [Step 2: Setup CDN for Widget Bundles](/tutorials/productionize-your-1fe-instance/cdn-setup/)** diff --git a/src/content/docs/tutorials/Productionize your 1fe instance/index.mdx b/src/content/docs/tutorials/Productionize your 1fe instance/index.mdx deleted file mode 100644 index 7bcfa18..0000000 --- a/src/content/docs/tutorials/Productionize your 1fe instance/index.mdx +++ /dev/null @@ -1,147 +0,0 @@ ---- -title: "Productionize Your 1fe Instance" -description: Transform your local 1fe setup into a production-ready system with robust infrastructure -sidebar: - order: 3 ---- - -import { SlRocket, SlTarget, SlCheck, SlUser, SlClock } from "react-icons/sl"; -import { - FaMicrosoft, - FaCloud, - FaNpm, - FaGithub, - FaDatabase, - FaShieldAlt, - FaRocket, -} from "react-icons/fa"; - -Ready to take your 1fe instance from development to production? This comprehensive tutorial will guide you through establishing the infrastructure and processes needed to deploy and manage your 1fe instance in a production environment. - -## Who is this for? - -This tutorial is designed for **platform teams** who have: - -
- -- **Completed initial 1fe evaluation** and decided to move forward with implementation -- **A working 1fe instance** running locally or in a development environment -- **Responsibility for production infrastructure** and deployment processes -- **Need to establish** enterprise-grade hosting, security, and CI/CD practices -- **Authority to provision** cloud infrastructure and configure deployment pipelines - -
- -## 📋 Prerequisites - -**Before starting this tutorial, ensure you have:** - -
- -- **Completed** the [Setup and Deploy a 1fe POC](/tutorials/setup-and-deploy-1fe-poc/) tutorial or equivalent experience -- **A working 1fe instance** running locally with at least one widget -- **Administrative access** to cloud infrastructure (Azure, AWS, or similar) -- **Understanding** of CI/CD concepts and deployment processes -- **Access to provision** hosting services, CDN, NPM registries, and configuration services - -
- -## What You'll Accomplish - -By the end of this tutorial, you'll have: - -
- -- **Production-ready hosting environment** for your 1fe instance with proper scaling and monitoring -- **CDN infrastructure** for efficient global widget bundle delivery -- **Private NPM registry** for secure package management and distribution -- **Configuration service** for dynamic settings management across environments -- **Automated CI/CD pipeline** for seamless deployments and rollbacks - -
- -## Tutorial Overview - -This tutorial consists of five progressive infrastructure components: - -### 1. Setup a Hosting Service for Your 1fe Instance - -**Time: ~45 minutes** - -
- -- Configure scalable hosting service for your 1fe instance - -
- -### 2. Setup a Static Hosting Service for Your Bundles - -**Time: ~30 minutes** - -
- -- Establish content delivery network(CDN) for widget bundles - -
- -### 3. Setup a NPM Registry - -**Time: ~20 minutes** - -
- -- Set up secure package management for widgets and dependencies - -
- -### 4. Setup a Configuration Service - -**Time: ~25 minutes** - -
- -- Implement dynamic configuration management to manage widget metadata including version information, deployment status, and dependencies - -
- -### 5. Setup a CI/CD System - -**Time: ~60 minutes** - -
- -- centralized CI/CD system to manage deployments across all widgets - -
- -## 🎯 Expected Outcomes - -After completing this tutorial, your organization will have: - -
- -- **Scalable infrastructure** capable of supporting multiple development teams -- **Automated processes** that reduce manual deployment effort and errors - -
- -## 🚀 Ready to Begin? - -This tutorial builds upon the foundation you've established with your 1fe proof-of-concept. We'll transform your development setup into an enterprise-grade production system. - -**→ [Start with Production Hosting Setup](/tutorials/productionize-your-1fe-instance/hosting-setup/)** - ---- - -## 💡 Need Help? - -
- -- **Infrastructure questions?** Reference our [How-to Guides](/how-to-guides/) -- **Configuration help?** Check the [1fe Server Reference](/reference/1fe-server-reference/) -- **General questions?** Visit our [FAQs](/learning/faqs/) -- **Terminology unclear?** See our [Terminology guide](/reference/terminology/) -- **Community support?** Join the [Community Discussions](https://github.com/docusign/1fe/discussions) -- **Found a bug?** Report it on [GitHub Issues](https://github.com/docusign/1fe/issues) - -
diff --git a/src/content/docs/tutorials/Productionize your 1fe instance/npm-registry.mdx b/src/content/docs/tutorials/Productionize your 1fe instance/npm-registry.mdx deleted file mode 100644 index b45bace..0000000 --- a/src/content/docs/tutorials/Productionize your 1fe instance/npm-registry.mdx +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: "Step 3: Setup NPM Registry" -description: Configure private NPM registry for secure package management -sidebar: - order: 3 ---- - -import { FaNpm, FaArrowRight } from "react-icons/fa"; - -A private NPM registry is essential for managing your 1fe widget packages securely and efficiently in a production environment. - -## 🎯 What You'll Set Up - -
- -- **Private NPM registry** for internal widget packages -- **Access controls** and authentication -- **CI/CD integration** for automated publishing -- **Package versioning** with changesets - -
- -## 📖 Complete Setup Guide - -Follow our detailed step-by-step guide for NPM registry setup: - -**[→ NPM Registry Setup Guide](/how-to-guides/infrastructure-setup/npm-registry-setup/)** - -## ✅ Verification - -After completing the setup, verify: - -
- -- Package publishing works from development environment -- Access controls work correctly for team roles -- CI/CD can publish packages automatically -- Package installation works from different environments - -
- -## 🚀 Next Step - -** [Step 4: Setup Configuration Service](/tutorials/productionize-your-1fe-instance/configuration-service/)** diff --git a/src/content/docs/tutorials/Setup and Deploy 1fe POC/deploy-poc.mdx b/src/content/docs/tutorials/Setup and Deploy 1fe POC/deploy-poc.mdx deleted file mode 100644 index 390b38c..0000000 --- a/src/content/docs/tutorials/Setup and Deploy 1fe POC/deploy-poc.mdx +++ /dev/null @@ -1,222 +0,0 @@ ---- -title: "Step 3: Deploy Your Proof of Concept" -description: Deploy your 1fe instance to production and demonstrate the complete workflow -sidebar: - order: 3 ---- - -import { - SlCloudDownload, - SlPencil, - SlRocket, - SlCloudUpload, - SlTarget, - SlCheck, - SlArrowRight, -} from "react-icons/sl"; -import { FcOk } from "react-icons/fc"; - -Perfect! You've set up your 1fe instance and experienced the development workflow. In this final part of the tutorial, you'll deploy your proof of concept to production. This will give you a live demo to share with stakeholders and demonstrate the complete development-to-deployment flow. - -## What You'll Learn - -
- -- How to deploy 1fe instances to production environments -- Setting up CDN infrastructure for widget assets -- Creating a demonstration-ready proof of concept -- Understanding the production deployment workflow - -
- -:::caution -**This is a POC deployment guide!** - -We are using public tooling in this guide to get something out on the internet so you can showcase your 1fe instance. If you're ready to set up a production environment with proper CDN infrastructure, CI/CD pipelines, and robust hosting, visit our [productionization guide](/how-to-guides/productionize). -::: - -### Setup the required github repositories - -You need two github repositories: - -**CDN Assets Repository** - -You need a repository for the `mock-cdn-assets` that will hold our assets. We will be using JSDelivr to serve these assets. JSDelivr works off of GitHub repositories and serves files based on Git tags. We already created a repository for our forked cdn assets on github.com and pushed our changes to that repository as part of the guide to get our setup locally. If you haven't done that, do that now so our mock-cdn-assets are available on github.com for JSDelivr to pick up from. - -**1fe Instance Repository** - -You need a repository for your 1fe instance that will be used to deploy your 1fe instance. - -## ☁️ Deploy our assets to a CDN - -We have already learnt how to host assets locally in the previous guide. Let's deploy to them a CDN so our hosted 1fe instance can access them. For this process, we will need to - -### Configure the 1fe instance first - -For this section, lets assume that you are going to use a git tag for your CDN assets like `v1.0.2`. You can pick any tag you like, but make sure to use the same tag in the next steps. We will use `` to refer to this tag in the rest of this guide. Based on this information (and with some more steps that you will take later), you need to make the following changes to your 1fe instance files. - -1. Point your 1fe instance to the new CDN assets for **live configurations**. Live configurations let you update widget versions, library versions, and dynamic settings without redeploying your 1fe instance - the configs are fetched at runtime! **[Find out more here](/learning/live-configurations/)** - - ```tsx title="src/config/ecosystem-configs.ts" {4,7,10} - // ... - export const configManagement: OneFEConfigManagement = { - widgetVersions: { - url: `https://cdn.jsdelivr.net/gh//@/integration/configs/widget-versions.json`, - }, - libraryVersions: { - url: `https://cdn.jsdelivr.net/gh//@/integration/configs/lib-versions.json`, - }, - dynamicConfigs: { - url: `https://cdn.jsdelivr.net/gh//@/integration/configs/live.json`, - }, - refreshMs: 30 * 1000, - }; - ``` - -2. Point your 1fe instance to the new CDN assets for critical libraries. - - ```tsx title="src/config/ecosystem-configs.ts" {3,5,9,10} - // ... - const shellBundleUrl = - isLocal || SERVER_BUILD_NUMBER === "local" - ? `http://localhost:3001/js/bundle.js` - : `https://cdn.jsdelivr.net/gh//@/${ENVIRONMENT}/shell/${SERVER_BUILD_NUMBER}/js/bundle.js`; - - const importMapOverrideUrl = isProduction - ? `https://cdn.jsdelivr.net/gh//@/${ENVIRONMENT}/libs/@1fe/import-map-overrides/3.1.1/dist/import-map-overrides-api.js` - : `https://cdn.jsdelivr.net/gh//@/${ENVIRONMENT}/libs/@1fe/import-map-overrides/3.1.1/dist/import-map-overrides.js`; - - export const criticalLibUrls = { - importMapOverride: importMapOverrideUrl, - systemJS: `https://cdn.jsdelivr.net/gh//@/${ENVIRONMENT}/libs/systemjs/6.14.0/dist/system.min.js`, - systemJSAmd: `https://cdn.jsdelivr.net/gh//@/${ENVIRONMENT}/libs/systemjs/6.14.0/dist/extras/amd.min.js`, - shellBundleUrl, - }; - ``` - -3. Update the CSP policy. - Update the CSP policies as defined in `src/csp-configs.ts` to allow jsdelivr domains(`https://cdn.jsdelivr.net`) -4. Now check this into your 1fe instance repository. That can help with deploying your 1fe instance later. - -### Add the 1fe instance bundle to the CDN - -When working on getting our setup to work locally, we already uploaded bundles for `widget-starter-kit` and `playground` to the CDN. We need to upload the shell bundle. - -You need to pick a random number to act as a build number for your 1fe instance. This will be used to create a unique folder in the CDN for your 1fe instance. Lets call it ``. - -1. Build the 1fe instance again using `yarn build` -2. Copy the bundle over to your `mock-cdn-assets` repository like so: - -```bash -mkdir -p mock-cdn-assets/integration/shell// -cp -r /dist/public/ mock-cdn-assets/integration/shell// -``` - -### Create and Push Tags for JSDelivr - -Let's now add all the changes you have made to your CDN assets repository and create a the git tag for them. This is crucial for JSDelivr to cache the assets and serve them correctly. - -1. **Create and push a Git tag:** - - ```bash - cd mock-cdn-assets - git remote - git add . - git tag v1.0.2 # Use your chosen tag here - git push origin main - git push origin v1.0.2 # Push the tag to GitHub - ``` - -2. **Your assets are now publicly accessible via JSDelivr URLs:** - - ``` - # Widget Starter Kit Bundle - https://cdn.jsdelivr.net/gh//mock-cdn-assets@v1.0.2/integration/widgets/@1fe/widget-starter-kit//js/1fe-bundle.js - - # playground Widget Bundle - https://cdn.jsdelivr.net/gh//@v1.0.2/integration/widgets/@1fe/playground//js/1fe-bundle.js - - # Live Configurations - https://cdn.jsdelivr.net/gh//@v1.0.2/integration/configs/live.json - ``` - -:::tip -**JSDelivr not reflecting your changes?** Try purging the cache at https://www.jsdelivr.com/tools/purge. Changes typically appear within a few minutes. -::: - -## 🌐 Deploy our 1fe instance to a hosting service - -Now that we have our CDN setup, let's deploy our 1fe instance to a hosted service such that it's pointing to our CDN. - -### Deploy the 1fe instance - -Your 1fe instance is now ready to be deployed to a server. You can choose any hosting service of your choice that is capable of serving a nodejs express app. Below are some services you can use and their documentation links to help you deploy your 1fe instance. - -| Service | Documentation | -| ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | -| [Render](https://render.com/) | https://render.com/docs/deploy-node-express-app | -| [Heroku](https://www.heroku.com/) | https://devcenter.heroku.com/articles/deploying-nodejs#deploy-your-application-to-heroku | -| [Railway](https://railway.app/) | https://docs.railway.com/guides/express | -| [Azure](https://azure.microsoft.com/en-us/services/app-service/) | https://learn.microsoft.com/en-us/azure/app-service/quickstart-nodejs?tabs=linux&pivots=development-environment-cli | -| [AWS](https://aws.amazon.com/) | https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/nodejs-quickstart.html#nodejs-quickstart-deploy | -| [Google cloud](https://cloud.google.com/) | https://cloud.google.com/appengine/docs/standard/nodejs/building-app/deploying-web-service | - -As a quick start, you can also use the links below with your 1fe instance repository URL to deploy it to either Render or Heroku. - -**Render Deployment** - -`https://render.com/deploy?repo=` - -**Heroku Deployment** - -`https://www.heroku.com/deploy?template=` - -After you have deployed your 1fe instance, you will be able to access it at the URL provided by your hosting service! - -## 🎉 Congratulations! Tutorial Complete! - -You have successfully completed the entire 1fe proof of concept tutorial! You now have a live, working 1fe instance that demonstrates the complete development-to-deployment workflow. - -## 🎯 What You've Accomplished - -- ✅ **Built a complete 1fe proof of concept** from scratch to production -- ✅ **Deployed to production** with CDN infrastructure and hosting -- ✅ **Experienced the full development workflow** from setup to deployment -- ✅ **Created a demonstrable example** to share with stakeholders -- ✅ **Understood 1fe's architecture and benefits** through hands-on experience - -## 🚀 What's Next? - -### For Immediate Use - -- **Share your POC** with stakeholders and team members -- **Demonstrate the development workflow** you just experienced -- **Evaluate 1fe's fit** for your organization's needs - -### For Production Implementation - -**Next Tutorial Series:** - -- **Take Ownership (Coming Soon)** - Take full control of your 1fe ecosystem with shared configurations, CI/CD infrastructure, and custom shell types - -**Advanced Implementation:** - -- **[Productionize Your 1fe Instance](/tutorials/productionize-your-1fe-instance/)** - Transform your POC into enterprise-ready infrastructure -- **[Authentication Setup](/how-to-guides/authentication/)** - Implement proper user authentication -- **[Custom Utilities](/how-to-guides/custom-utilities/)** - Build platform-specific utilities for your teams - -### For Deeper Understanding - -- **[What is 1fe?](/learning/what-is-1fe/)** - Dive deeper into 1fe concepts and architecture -- **[Infrastructure Setup Guides](/how-to-guides/#infrastructure-setup)** - Solve specific implementation challenges -- **[1fe Server Reference](/reference/1fe-server-reference/)** - Access technical documentation and API references - ---- - -## 💡 Need Help? - -- **Questions?** Check our [FAQs](/learning/faqs/) or [Community Discussions](https://github.com/docusign/1fe/discussions) -- **Terminology unclear?** Visit our [Terminology guide](/reference/terminology/) -- **Found a bug?** Report it on [GitHub Issues](https://github.com/docusign/1fe/issues) - -**You've successfully proven that 1fe can standardize your frontend development while maintaining team independence. Welcome to the 1fe community!** 🎊 diff --git a/src/content/docs/tutorials/Setup and Deploy 1fe POC/develop-locally.mdx b/src/content/docs/tutorials/Setup and Deploy 1fe POC/develop-locally.mdx deleted file mode 100644 index 3499fa6..0000000 --- a/src/content/docs/tutorials/Setup and Deploy 1fe POC/develop-locally.mdx +++ /dev/null @@ -1,307 +0,0 @@ ---- -title: "Step 2: Develop Your First Widget" -description: Learn the development workflow and build a custom widget -sidebar: - order: 2 ---- - -import { - SlSocialDropbox, - SlAnchor, - SlCloudDownload, - SlWrench, - SlCloudUpload, - SlTarget, - SlCheck, - SlArrowRight, -} from "react-icons/sl"; -import { FcOk } from "react-icons/fc"; - -Great! You now have a working 1fe instance from Step 1. In this second step, you'll dive into the development experience by creating and customizing widgets. This is where you'll see the real power of 1fe's development workflow. - -## What You'll Learn - -
- -- How to explore and test existing widgets -- The widget development workflow and tooling -- Platform utilities and how widgets integrate with the shell - -
- -## 🔍 Explore the local 1fe instance - -### Test Sample plugins - -
- -1. **Visit `http://localhost:3001/widget-starter-kit/utils` to view the example starter plugin** -2. **Click the button `utils.context.get`** - ![A rocketship in space](./assets/example-child-widget.png) -3. **What just happened?** - - 1. 1fe loaded and rendered the _plugin_ tied to the `/widget-starter-kit` route. - 2. When `utils.context.get` was clicked, the plugin loaded a child _widget_ via the magic of **platform utilities**! Platform utilities are built-in services for common tasks like context management, event communication, and storage. ✨ **[See what other utilities](/reference/platform-utilities/overview/)** are in your toolkit. - -
- -:::tip[The Magic Behind the Scenes 🎭] -1fe loads the latest widget bundles and assets from a **CDN** (Content Delivery Network) - pretty cool, right? This hosts your widget bundles and shared dependencies, enabling dynamic loading so your widgets can update independently without touching the main app! **[Discover how this magic works](/learning/externalized-libraries/)** 🪄 -::: - -Read more about [widgets and plugins](/learning/widgets/) and [platform utilities](/reference/platform-utilities/overview/). - -### 🔧 Override widget starter kit with your local plugin - -In the above section, we explored the example starter plugin. Let's override that example plugin to use our plugin running locally. - -
- -1. **If not already running, Run `yarn dev` in `1fe-widget-starter-kit/`** - - ```bash - cd 1fe-widget-starter-kit - yarn dev - ``` - - 1fe CLI will serve the widget bundle at `http://localhost:8080/js/1fe-bundle.js` - -2. **Visit `http://localhost:3001/widget-starter-kit` and click the `{...}` button at the bottom right corner of the screen.** ![Import map overrides button showing three dots in brackets](./assets/three-dots.png) -3. **Search for `@1fe/widget-starter-kit` within the shelf and select the matching module** - - ![Import map shelf](./assets/import-map-shelf.png) - -4. **In the `Override URL` field, enter `http://localhost:8080/js/1fe-bundle.js` and click `Apply override`.** - - ![Import map override modal](./assets/override-modal.png) - -5. **Make changes to your widget and observe the changes in the browser.** - -
- -## ⚙️ Customize your 1fe instance - -In the previous step, we overrode the example plugin to use our local plugin. Now let's look at how to host your plugin locally so it shows up by deafult in the 1fe instance. - -### Build plugin assets - -#### Setup widget-starter-kit - -
- -1. **Make any content change to `1fe-widget-starter-kit/src`** - - ```tsx title="1fe-widget-starter-kit/src/app1.tsx" {10} - import { platformProps } from "@devhub/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 = (props) => { - useEffect(() => { - platformProps.utils.appLoadTime.end(); - console.log("Hello from app1!"); - }, []); - - return ; - }; - - export default withProvider(RootWrapper); - ``` - -2. **Build the plugin within `1fe-widget-starter-kit` directory** - - :::caution - **Keep your 1fe instance running in the background**. - - 1fe CLI will need the development server for the build process. This will later be pointed to a deployed environment once your 1fe instance is hosted. - ::: - - ```bash - # 1fe - cd 1fe-widget-starter-kit - yarn build:widget - ``` - -
- -:::tip -1fe CLI will build the widget. Observe the assets within the `dist` folder. -::: - -![dist folder contents](./assets/example-plugin-dist.png) - -#### Setup the playground widget - -We'll also need the playground widget for our 1fe instance. The playground widget provides essential development tooling and runtime utilities. - -
- -1. **Fork the [1fe-playground](https://github.com/docusign/1fe-playground) repository to your GitHub account.** - - ```bash - git clone https://github.com//1fe-playground.git - cd 1fe-playground - ``` - -2. **Install dependencies and build the widget:** - - ```bash - yarn install - yarn build:widget - ``` - -
- -:::tip -The playground widget build will also generate assets in the `dist` folder. -::: - -### **Host the widgets locally** - -
- -1. Fork this [mock-cdn-assets](https://github.com/docusign/mock-cdn-assets/tree/main) repository - This repository contains the live configurations and widget assets per environment that power [demo.1fe.com](https://demo.1fe.com). We will use this as a jumping off point to get our own version of the assets -2. Create a new directory within `integration/widgets/@1fe/widget-starter-kit` of your forked cdn repo. The directory name should be the version from the package.json of the widget-starter-kit repository. (e.g `1.0.2`). -3. Upload the contents of the `1fe-widget-starter-kit/dist/` directory to the new directory. -4. Create a new directory within `integration/widgets/@1fe/playground` of your forked cdn repo. The directory name should be the version from the package.json of the playground repository (e.g `1.0.50`). -5. Upload the contents of the `1fe-playground/dist/` directory to the playground directory. Following is an image which showcases what the directory structure will look like after you have moved the code over. - ![dist folder assets copied to CDN](./assets/example-plugin-cdn-assets.png) -6. Serve them locally using the [serve package](https://www.npmjs.com/package/serve) by running the following command - ``` - npx serve -C - ``` - -
- -### Use the new widget assets in our 1fe instance - -One of the key features of 1fe is the ability to dynamically load widgets and plugins via [Live Configurations](../../main-concepts/live-configurations). We will now take advantage of these configurations to get our local 1fe instance to get the config's from our local CDN. - -#### Update widget-versions.json - -The `widget-versions.json` file defines the available versions for each widget that can be loaded by the 1fe platform. Create `integration/configs/widget-versions.json` file within your forked mock-cdn-assets repository and update it like so: - -```json title="widget-versions.json" -[ - { - "widgetId": "@1fe/playground", - "version": "" - }, - { - "widgetId": "@1fe/widget-starter-kit", - "version": "" - } -] -``` - -#### Update live.json - -The [`live.json`](https://1fe-a.akamaihd.net/integration/configs/live.json) file contains the runtime configuration for the plugins that are being loaded - -
- -1. Locate `integration/configs/live.json` within your forked mock-cdn-assets repository and make the following changes: -2. Update the basePrefix to point to your server running locally through the serve package -3. Remove the `sample-widget` and `sample-widget-with-auth` widget configurations as they are not needed for this example. Following is what the diff will look like. Also, here is a [PR](https://github.com/docusign/mock-cdn-assets/pull/28/files) showcasing these changes - - ```diff title="live.json" - { - + "libraries": { - + "basePrefix": "http://localhost:3000/integration/libs/" - + }, - "widgets": { - + "basePrefix": "http://localhost:3000/integration/widgets/", - "configs": [ - { - "widgetId": "@1fe/playground", - "plugin": { - "enabled": true, - "route": "/widget-starter-kit" - } - }, - - { - - "widgetId": "@1fe/sample-widget", - - "plugin": { - - "enabled": true, - - "route": "/sample-widget" - - } - - }, - - { - - "widgetId": "@1fe/sample-widget-with-auth", - - "plugin": { - - "enabled": true, - - "route": "/sample-widget-with-auth", - - "auth": { - - "authenticationType": "required" - - } - - } - - } - ] - } - } - ``` - -4. Confirm that the updated Live Configurations are working by visiting the following link: - ``` - http://localhost:3000/integration/configs/live.json - ``` - -
- -#### Point your local 1fe instance to the new CDN assets - -To point the 1fe instance to the new CDN assets, update the `src/config/ecosystem-configs.ts` file with the following changes: - -```tsx title="src/config/ecosystem-configs.ts" {4,7,10} -// ... -export const configManagement: OneFEConfigManagement = { - widgetVersions: { - url: `http://localhost:3000/integration/configs/widget-versions.json`, - }, - libraryVersions: { - url: `http://localhost:3000/integration/configs/lib-versions.json`, - }, - dynamicConfigs: { - url: `http://localhost:3000/integration/configs/live.json`, - }, - refreshMs: 30 * 1000, -}; -``` - -Navigate to [starter kit locally](http://localhost:3001/widget-starter-kit/utils) and check the console for the message "Hello from app1!" to confirm that your changes are being reflected. - -##### Tada! - -![A rocketship in space](./assets/example-plugin-change.png) - -:::note[🔒 CSP Gone Wrong!] -**Whoops! Page reload causing CSP issues?** - -If you refresh the page and see Content Security Policy errors blocking you from loading assets, don't panic! 🚨 - -You need to update the CSP settings in the 1fe instance(`src/csp-configs.ts`) to allow them(`http://localhost:3000/`). -::: - -## 🎉 You have a local 1fe instance! - -You've successfully set up local development for your 1fe widgets! You can move on to the next section if you want to deploy your 1fe instance quickly to showcase it's benefits to your team. Or, you can use the below links to jump to different sections to learn more. - -## 🎯 What You've Accomplished - -- ✅ **Explored the widget development workflow** using the playground -- ✅ **Learned about platform utilities** and how widgets integrate with the shell -- ✅ **Understood the development tools** and local development process -- ✅ **Built hands-on experience** with widget creation and testing - -## 👉 Next Step - -Now that you understand how to develop widgets locally, it's time to take your proof of concept to production and show stakeholders a complete deployment. - -**→ [Step 3: Deploy Your Proof of Concept](/tutorials/setup-and-deploy-1fe-poc/deploy-poc/)** - -In the final step, you'll deploy your instance to a production environment. - ---- diff --git a/src/content/docs/tutorials/Setup and Deploy 1fe POC/index.mdx b/src/content/docs/tutorials/Setup and Deploy 1fe POC/index.mdx deleted file mode 100644 index e016657..0000000 --- a/src/content/docs/tutorials/Setup and Deploy 1fe POC/index.mdx +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: "Setup and deploy 1fe POC" -description: Complete tutorial for platform teams to evaluate and set up 1fe -sidebar: - order: 1 ---- - -import { - SlTarget, - SlUser, - SlClock, - SlCheck, - SlWrench, - SlAnchor, - SlArrowRight, -} from "react-icons/sl"; - -This tutorial will guide you through setting up, developing with, and deploying a 1fe instance as a proof of concept for your organization. - -## Who is this for? - -This tutorial is designed for **platform teams** who are: - -- **Evaluating micro-frontend solutions** for their organization. Micro-frontends let teams build, deploy, and maintain parts of a frontend application independently (psst... **[find out why they're the future](/learning/why-1fe/)** 🚀) - -- **Responsible for frontend infrastructure** and developer experience -- **Looking to standardize** development practices across teams -- **Considering 1fe** as a solution for managing multiple frontend applications -- **Need to demonstrate** 1fe's capabilities to stakeholders and leadership - -## 📋 Prerequisites - -
- -- Experience with Node.js and modern JavaScript tooling -- Understanding of frontend build processes -- Basic familiarity with micro-frontend concepts -- Access to deploy applications (for the final step) - -
- -## Tutorial Overview - -This tutorial consists of three progressive steps that build upon each other: - -### Step 1: Create Your 1fe Instance - -- Set up a local 1fe instance from scratch -- Get the basic shell running locally - -### Step 2: Develop Your First Widget - -- Create and develop a widget using the playground -- Learn the development workflow and tooling - -### Step 3: Deploy Your Proof of Concept - -- Deploy your instance to a production-like environment - -## What You'll Accomplish - -By the end of this tutorial, you'll have: - -- **A working 1fe instance** running in production -- **Hands-on experience** with the complete development workflow -- **A demonstrable proof of concept** to show stakeholders -- **Understanding of 1fe's benefits** and capabilities - -## 🚀 Ready to Begin? - -**→ [Step 1: Create Your 1fe Instance](/tutorials/setup-and-deploy-1fe-poc/installation/)** - ---- - -### Need Help? - -- Check the [FAQs](/learning/faqs/) for common questions -- Reference the [Terminology](/reference/terminology/) for unfamiliar concepts -- Explore [Learning](/learning/) for deeper conceptual understanding -- Join [Community Discussions](https://github.com/docusign/1fe/discussions) for help -- Report bugs on [GitHub Issues](https://github.com/docusign/1fe/issues) diff --git a/src/content/docs/tutorials/Setup and Deploy 1fe POC/installation.mdx b/src/content/docs/tutorials/Setup and Deploy 1fe POC/installation.mdx deleted file mode 100644 index 4c7deab..0000000 --- a/src/content/docs/tutorials/Setup and Deploy 1fe POC/installation.mdx +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: "Step 1: Create Your 1fe Instance" -description: Set up a local 1fe instance and understand the core architecture -sidebar: - order: 1 ---- - -import { FcSettings, FcElectronics } from "react-icons/fc"; - -In this first part of our proof of concept tutorial, you'll set up a local **1fe instance** from scratch. - -New to 1fe? It's a micro-frontend platform that lets teams build independent applications (widgets) that work together seamlessly. **[Find out what makes it special](/learning/what-is-1fe/)** ✨ before we dive in! This will give you hands-on experience with the core architecture. - -## What You'll Learn - -- How to scaffold a new 1fe instance - -## 📋 Prerequisites - -- Node.js 22.x.x+ -- Yarn 4.x.x+ - -## 🔧 Manual Installation - -
-1. **Scaffold a starter application:** - -```bash -npx @1fe/create-1fe-app -``` - -2. **Clone the 1fe widget starter kit (WSK):** - -We'll also grab the **widget starter kit** - it's a pre-configured template with all the tooling and example code you need to create widgets. Think of it as your widget creation toolkit! 🛠️ **[Learn more about widgets](/learning/widgets/)** and why they're awesome. - -```bash -git clone https://github.com/docusign/1fe-widget-starter-kit.git -``` - -3. **Set up both the repos:** - -First you need to build the 1fe monorepo and the starter kit. - -```bash -cd # adjust this to fit your directory structure -yarn && yarn build -``` - -Then, you need to set up the starter kit. - -```bash -cd 1fe-widget-starter-kit # adjust this to fit your directory structure -yarn -``` - -4. **Run the starter app development server** - -```bash -cd # adjust this to fit your directory structure -yarn dev -``` - -You can now visit your instance at [http://localhost:3000](http://localhost:3000). You will see this mirror our demo website [here](https://demo.1fe.com/). We will take a look later at how to customize this instance. - -5. **Run the development server for the WSK** - -```bash -cd 1fe-widget-starter-kit/ # adjust this to fit your directory structure -yarn dev -``` - -This will open WSK at the following [link](http://localhost:3001/playground?widgetUrl=http%3A%2F%2F127.0.0.1%3A8080%2Fjs%2F1fe-bundle.js). - -You now have a functioning 1fe instance running locally! 🎉 - -## 🎯 What You've Accomplished - -- ✅ **Set up a complete 1fe development environment** -- ✅ **Created your first 1fe instance** with server and shell components -- ✅ **Understood the basic architecture** of how 1fe works - -## 👉 Next Step - -Now that you have a working 1fe instance, it's time to learn how to build widgets and understand the development workflow. - -**→ [Step 2: Develop Your First Widget](/tutorials/setup-and-deploy-1fe-poc/develop-locally/)** - -Continue to learn the development workflow and build a custom widget. - -
diff --git a/src/content/docs/tutorials/Setup and Deploy 1fe POC/assets/example-child-widget.png b/src/content/docs/tutorials/assets/example-child-widget.png similarity index 100% rename from src/content/docs/tutorials/Setup and Deploy 1fe POC/assets/example-child-widget.png rename to src/content/docs/tutorials/assets/example-child-widget.png diff --git a/src/content/docs/tutorials/Setup and Deploy 1fe POC/assets/example-plugin-cdn-assets.png b/src/content/docs/tutorials/assets/example-plugin-cdn-assets.png similarity index 100% rename from src/content/docs/tutorials/Setup and Deploy 1fe POC/assets/example-plugin-cdn-assets.png rename to src/content/docs/tutorials/assets/example-plugin-cdn-assets.png diff --git a/src/content/docs/tutorials/Setup and Deploy 1fe POC/assets/example-plugin-change.png b/src/content/docs/tutorials/assets/example-plugin-change.png similarity index 100% rename from src/content/docs/tutorials/Setup and Deploy 1fe POC/assets/example-plugin-change.png rename to src/content/docs/tutorials/assets/example-plugin-change.png diff --git a/src/content/docs/tutorials/Setup and Deploy 1fe POC/assets/example-plugin-dist.png b/src/content/docs/tutorials/assets/example-plugin-dist.png similarity index 100% rename from src/content/docs/tutorials/Setup and Deploy 1fe POC/assets/example-plugin-dist.png rename to src/content/docs/tutorials/assets/example-plugin-dist.png diff --git a/src/content/docs/tutorials/Setup and Deploy 1fe POC/assets/import-map-shelf.png b/src/content/docs/tutorials/assets/import-map-shelf.png similarity index 100% rename from src/content/docs/tutorials/Setup and Deploy 1fe POC/assets/import-map-shelf.png rename to src/content/docs/tutorials/assets/import-map-shelf.png diff --git a/src/content/docs/tutorials/Setup and Deploy 1fe POC/assets/override-modal.png b/src/content/docs/tutorials/assets/override-modal.png similarity index 100% rename from src/content/docs/tutorials/Setup and Deploy 1fe POC/assets/override-modal.png rename to src/content/docs/tutorials/assets/override-modal.png diff --git a/src/content/docs/tutorials/Setup and Deploy 1fe POC/assets/three-dots.png b/src/content/docs/tutorials/assets/three-dots.png similarity index 100% rename from src/content/docs/tutorials/Setup and Deploy 1fe POC/assets/three-dots.png rename to src/content/docs/tutorials/assets/three-dots.png diff --git a/src/content/docs/tutorials/developing-your-first-widget.mdx b/src/content/docs/tutorials/developing-your-first-widget.mdx new file mode 100644 index 0000000..6c81aa7 --- /dev/null +++ b/src/content/docs/tutorials/developing-your-first-widget.mdx @@ -0,0 +1,549 @@ +--- +title: "Developing Your First Widget" +description: Build widgets for an existing 1fe ecosystem using development tools and best practices +sidebar: + order: 2 +--- + +Let's build a widget for an existing 1fe ecosystem. You'll set up your development environment, use the playground for rapid iteration, configure your widget, and prepare it for deployment. + +This tutorial is for frontend developers working with React in organizations that have a 1fe instance. + +:::tip[Check with your organization first] +Your organization may have custom widget starter kits, internal development guidelines, or specific deployment processes. Use those instead of the standard tools shown here - the concepts remain the same. +::: + +**Prerequisites:** Node.js 22+, yarn, a code editor, access to a 1fe instance, and basic React knowledge. + +## What We're Building + +**[🚀 Getting Started](#🚀-getting-started)** - Set up your development environment and project structure +**[🎯 Using the Playground](#🎯-using-the-playground)** - Develop and test your widget interactively +**[⚙️ Widget Configuration](#⚙️-widget-configuration)** - Configure contracts and platform integration +**[🔨 Building and Testing](#🔨-building-and-testing)** - Prepare your widget for deployment + +Let's start building. + +--- + +## 🚀 Getting Started + +Let's set up your widget development environment. We'll clone the [widget starter kit](https://github.com/docusign/1fe-widget-starter-kit) and get your development server running. + +### Prerequisites Check + +```bash +# Check Node.js version (22+ required) +node --version + +# Check yarn version (4.x.x) +yarn --version +``` + +### Clone the Widget Starter Kit + +A [widget](/learning/widgets/) is a self-contained React component that runs in the 1fe ecosystem. + +```bash +# Clone the widget starter kit +git clone https://github.com/docusign/1fe-widget-starter-kit.git my-first-widget + +# Navigate to the project +cd my-first-widget + +# Install dependencies +yarn install +``` + +### Project Structure + +``` +my-first-widget/ +├── src/ +│ ├── components/ # Reusable React components +│ ├── contract.ts # Widget contract definition +│ ├── app1.tsx # Main widget entry point +│ └── widget.ts # Default widget export +├── .1fe.config.ts # Widget build configuration +└── package.json # Dependencies and scripts +``` + +**Key files:** + +- `src/app1.tsx` - Your main widget component with access to [platform utilities](/reference/platform-utilities/overview/) +- `src/contract.ts` - Defines the [contract](/learning/widgets/#contracts) between your widget and the platform +- `.1fe.config.ts` - Controls how your widget is [built and configured](/reference/1fe-config-reference/) + +### Start Development Server + +:::note[1fe Instance Required] +This requires a running [1fe instance](/learning/what-is-1fe/). If you don't have one, follow the [Setup and Deploy a 1fe POC](/tutorials/setup-and-deploy-1fe-poc/) tutorial first. +::: + +```bash +# Start the development server +yarn dev +``` + +This will: + +
+ +- Compile your widget +- Start a local development server +- Open your widget in the [1fe Playground](/learning/playground/) +- Enable hot reloading for development + +
+ +### Verify Your Setup + +**1. Check the bundle URL:** +Visit [http://localhost:8080/js/1fe-bundle.js](http://localhost:8080/js/1fe-bundle.js) - you should see JavaScript code. + +**2. Open in playground:** +If you don't have a 1fe instance, use the demo playground: +[http://demo.1fe.com/playground?widgetUrl=http%3A%2F%2F127.0.0.1%3A8080%2Fjs%2F1fe-bundle.js](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 add a success alert: + +```typescript title="src/app1.tsx" +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 = (props) => { + useEffect(() => { + platformProps.utils.appLoadTime.end(); + }, []); + + return ( +
+ + +
+ ); +}; + +export default withProvider(RootWrapper); +``` + +Save the file - your widget should recompile automatically and show the success banner. + +Your development environment is ready! Your widget has access to platform utilities, shared dependencies, and can communicate with other widgets through the event system. + +--- + +## 🎯 Using the Playground + +The 1fe Playground is your primary development environment for testing and iterating on widgets. It provides an isolated sandbox where you can develop without needing the full application setup. + +### Playground Features + +**Widget Loading**: Load your widget from any URL for testing +**Live Reloading**: See changes instantly as you develop +**Platform Simulation**: Test how your widget behaves in different platform contexts +**Debug Tools**: Access browser dev tools and widget-specific debugging + +### Development Workflow + +**1. Start your widget development server** (if not already running): + +```bash +yarn dev +``` + +**2. The playground automatically opens** with your widget loaded at: + +``` +http://localhost:3001/playground?widgetUrl=http%3A%2F%2F127.0.0.1%3A8080%2Fjs%2F1fe-bundle.js +``` + +**3. Make changes to your widget code** and watch them appear instantly in the playground. + +### Testing Widget Features + +**Platform Integration**: Test how your widget receives props from the platform: + +```typescript title="src/app1.tsx" +const RootWrapper: React.FC = (props) => { + useEffect(() => { + platformProps.utils.appLoadTime.end(); + // Log props to see what your widget receives + console.log("Widget props:", props); + }, []); + + return ; +}; +``` + +**Platform Utilities**: Test built-in utilities like logging, storage, and context: + +```typescript +// Test logging +platformProps.utils.logger.log("Hello from widget!"); + +// Test context management +const context = platformProps.utils.context.get(); +platformProps.utils.context.set({ myData: "test" }); + +// Test event communication +platformProps.utils.eventBus.emit("widget-event", { data: "test" }); +``` + +**State Management**: Develop and test your widget's internal state: + +```typescript +const [widgetState, setWidgetState] = useState({ + loading: false, + data: null, + error: null, +}); +``` + +### Playground Environment + +The playground provides a clean testing environment where you can: + +
+ +- Test different widget configurations +- Simulate various platform states +- Debug widget behavior in isolation +- Validate widget contracts and props + +
+ +**Hot Reloading**: Any changes you make to your widget code will automatically rebuild and reload in the playground, making development rapid and efficient. + +--- + +## ⚙️ Widget Configuration + +Widget configuration defines how your widget integrates with the 1fe platform. This includes contracts, dependencies, and build settings. + +### Widget Contract + +The contract defines what data your widget expects from the platform and what it provides back: + +```typescript title="src/contract.ts" +import { PlatformPropsType } from "@1fe/shell"; + +// Define what props your widget expects from the host application +export type HostPropsContract = { + userId?: string; + theme?: "light" | "dark"; + locale?: string; + // Add your specific props here +}; + +// Combined widget props (host + platform) +export type WidgetProps = { + host: HostPropsContract; + platform: PlatformPropsType; +}; +``` + +**Host Props**: Data passed from the host application to your widget +**Platform Props**: Built-in platform utilities and context + +### Build Configuration + +The `.1fe.config.ts` file controls how your widget is built and deployed: + +```typescript title=".1fe.config.ts" +import { OneFeConfiguration } from "@1fe/cli"; +import { getBaseConfig } from "@1fe/sample-widget-base-config"; + +const configuration: OneFeConfiguration = { + // Base configuration from your organization + baseConfig: getBaseConfig, + + // Override specific settings + webpack: { + // Custom webpack configuration + externals: { + // Define external dependencies + react: "React", + "react-dom": "ReactDOM", + }, + }, + + // Widget metadata + widget: { + name: "my-first-widget", + version: "1.0.0", + }, +}; + +export default configuration; +``` + +### Platform Integration + +Your widget integrates with the platform through several mechanisms: + +**Platform Utilities**: Access built-in services: + +```typescript +import { platformProps } from "@1fe/shell"; + +// Logging +platformProps.utils.logger.log("Widget loaded"); +platformProps.utils.logger.error("Something went wrong"); + +// App load time tracking +platformProps.utils.appLoadTime.end(); + +// Context management +const globalContext = platformProps.utils.context.get(); +platformProps.utils.context.set({ widgetData: data }); + +// Event communication +platformProps.utils.eventBus.on("global-event", handleEvent); +platformProps.utils.eventBus.emit("widget-ready", { widgetId: "my-widget" }); +``` + +**Shared Dependencies**: Leverage externalized libraries: + +```typescript +// These are provided by the platform, not bundled with your widget +import React from "react"; +import { Button, Alert } from "antd"; +``` + +**Widget Provider**: Wrap your widget with the provider for platform integration: + +```typescript title="src/withProvider.tsx" +import React from "react"; +import { WidgetProps } from "./contract"; + +export const withProvider = (Component: React.ComponentType) => { + return (props: WidgetProps) => { + // Add any widget-level providers here + return ; + }; +}; +``` + +### Configuration Best Practices + +**Contract Design**: Keep contracts simple and focused +**Dependency Management**: Use externalized dependencies when possible +**Error Handling**: Implement robust error boundaries +**Performance**: Optimize bundle size and loading + +--- + +## 🔨 Building and Testing + +Prepare your widget for deployment by building, testing, and validating it works correctly in different environments. + +### Building Your Widget + +**Development Build** (for testing): + +```bash +yarn build:widget +``` + +This creates a development build in the `dist/` folder with source maps and debugging information. + +**Production Build** (for deployment): + +```bash +yarn build:widget --mode production +``` + +This creates an optimized production build with minification and optimization. + +### Testing Strategies + +**Unit Testing**: Test individual components and functions: + +```typescript title="src/__tests__/widget.test.tsx" +import { render, screen } from "@testing-library/react"; +import Widget from "../app1"; + +describe("Widget", () => { + it("renders without crashing", () => { + const mockProps = { + host: {}, + platform: {} as any, + }; + + render(); + expect(screen.getByText("Widget Ready!")).toBeInTheDocument(); + }); +}); +``` + +**Integration Testing**: Test widget integration with the platform: + +```bash +# Run tests +yarn test + +# Run tests with coverage +yarn test --coverage +``` + +**Playground Testing**: Manual testing in the playground environment +**End-to-end Testing**: Test in a real 1fe instance + +### Validation Checklist + +Before deploying your widget, verify: + +**✅ Functionality**: + +
+ +- Widget loads without errors +- All features work as expected +- Props are handled correctly +- Error states are handled gracefully + +
+ +**✅ Performance**: + +
+ +- Bundle size is optimized +- Loading time is acceptable +- No memory leaks +- Efficient rendering + +
+ +**✅ Integration**: + +
+ +- Platform utilities work correctly +- Event communication functions +- Shared dependencies load properly +- Contract is fulfilled + +
+ +**✅ Quality**: + +
+ +- Code passes linting +- Tests pass +- No console errors +- Accessibility standards met + +
+ +### Deployment Preparation + +**Bundle Analysis**: Check your bundle size and dependencies: + +```bash +yarn analyze +``` + +**Environment Configuration**: Ensure your widget works in different environments: + +
+ +- Development (localhost) +- Staging (pre-production) +- Production (live) + +
+ +**Documentation**: Document your widget's: + +
+ +- Contract and expected props +- Dependencies and requirements +- Usage instructions +- Configuration options + +
+ +### Deployment Process + +**1. Build for production**: + +```bash +yarn build:widget --mode production +``` + +**2. Upload to CDN**: Deploy your widget bundle to your organization's CDN + +**3. Update configuration**: Add your widget to the platform's configuration + +**4. Test in production**: Verify everything works in the live environment + +**5. Monitor**: Watch for errors and performance issues + +Your widget is now ready for production deployment! + +--- + +## 🎉 Congratulations! Tutorial Complete! + +You've successfully built your first 1fe widget! You now understand the complete widget development workflow from setup to deployment. + +### What You've Accomplished + +
+ +- ✅ **Set up a complete widget development environment** +- ✅ **Used the playground for rapid development and testing** +- ✅ **Configured widget contracts and platform integration** +- ✅ **Built and tested your widget for deployment** +- ✅ **Prepared your widget for production deployment** + +
+ +### What's Next? + +**For Immediate Development:** + +
+ +- Explore more [platform utilities](/reference/platform-utilities/overview/) +- Learn about [widget patterns and best practices](/how-to-guides/) +- Understand [shared configurations](/learning/shared-configurations/) + +
+ +**For Advanced Development:** + +
+ +- **[Custom Utilities](/how-to-guides/custom-utilities/)** - Build platform-specific utilities +- **[Authentication](/how-to-guides/authentication/)** - Implement user authentication in widgets +- **[Override Shell Components](/how-to-guides/override-shell-components/)** - Customize the platform experience + +
+ +**For Production:** + +
+ +- **[Productionize Your 1fe Instance](/tutorials/productionize-your-1fe-instance/)** - Set up enterprise infrastructure +- **[CI/CD for Widgets](/how-to-guides/ci-cd/)** - Automate widget deployment +- **[Monitoring and Debugging](/how-to-guides/monitoring/)** - Track widget performance + +
+ +**You're now part of the 1fe developer community! Start building amazing widgets that deliver value while maintaining independence.** 🚀 diff --git a/src/content/docs/tutorials/index.mdx b/src/content/docs/tutorials/index.mdx index beb1762..e891d69 100644 --- a/src/content/docs/tutorials/index.mdx +++ b/src/content/docs/tutorials/index.mdx @@ -1,33 +1,23 @@ --- title: Tutorials -description: Step-by-step guides to help you learn and build with 1fe +description: Learn 1fe by building real projects sidebar: order: 0 --- -import { FcGraduationCap, FcElectronics, FcSupport } from "react-icons/fc"; +## 🎓 Tutorials -## Tutorials +Learn **1fe** by building real projects. These tutorials will take you from your first 1fe instance to production-ready infrastructure. -Welcome to our hands-on tutorials! These step-by-step guides will help you learn **1fe** by building real projects. +New to 1fe? **[Start here to understand what 1fe is](/learning/what-is-1fe/)** before diving in. -**New to 1fe?** No worries! 😊 Each tutorial includes fun links to key concepts as you encounter them. **[Click here to see what 1fe is all about](/learning/what-is-1fe/)** ✨ +## 🛤️ Choose Your Path -## Available Tutorials +**[Setup and Deploy a 1fe POC](/tutorials/setup-and-deploy-1fe-poc)** +Create your first 1fe instance, develop a widget, and deploy a proof of concept. -| Tutorial | Description | Audience | -| ---------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | -| [**Setup and Deploy a 1fe POC**](/tutorials/setup-and-deploy-1fe-poc/) | Learn how to set up your first 1fe instance, develop widgets locally, and deploy a proof of concept. Perfect for initial evaluation and demonstration. | Platform teams evaluating 1fe | -| [**Developing Your First Widget**](/tutorials/developing-your-first-widget/) | Complete guide for frontend developers to create, develop, and deploy widgets in an existing 1fe ecosystem using organization tools and best practices. | Frontend developers | -| **Take Ownership** (Coming Soon) | Essential infrastructure setup for platform teams to take full control of their 1fe ecosystem with shared configurations, CI/CD, and custom shell types. | Platform teams implementing 1fe | -| [**Productionize Your 1fe Instance**](/tutorials/productionize-your-1fe-instance/) | Transform your development setup into production-ready infrastructure with hosting, CDN, CI/CD | Platform teams implementing 1fe | +**[Developing Your First Widget](/tutorials/developing-your-first-widget)** +Build widgets for an existing 1fe ecosystem using development tools and best practices. ---- - -## Need Help? - -- **First time with 1fe?** Start with our [Welcome page](/start-here/) to understand the basics -- **Looking for specific solutions?** Check our [How-to Guides](/how-to-guides/) -- **Want to understand concepts?** Visit our [Learning section](/learning/) -- **Have questions?** Join the [Community Discussions](https://github.com/docusign/1fe/discussions) -- **Found a bug?** Report it on [GitHub Issues](https://github.com/docusign/1fe/issues) +**[Productionize Your 1fe Instance](/tutorials/productionize-your-1fe-instance)** +Transform your development setup into production infrastructure with hosting, CDN, and CI/CD. diff --git a/src/content/docs/tutorials/productionize-your-1fe-instance.mdx b/src/content/docs/tutorials/productionize-your-1fe-instance.mdx new file mode 100644 index 0000000..0116bf8 --- /dev/null +++ b/src/content/docs/tutorials/productionize-your-1fe-instance.mdx @@ -0,0 +1,449 @@ +--- +title: "Productionize Your 1fe Instance" +description: Transform your development setup into production infrastructure with hosting, CDN, and CI/CD +sidebar: + order: 3 +--- + +Let's transform your 1fe development setup into enterprise-grade production infrastructure. You'll set up hosting, CDN, NPM registry, configuration service, and CI/CD pipeline. + +This tutorial is for platform teams who have completed the [Setup and Deploy a 1fe POC](/tutorials/setup-and-deploy-1fe-poc/) tutorial and are ready to move to production. + +**Prerequisites:** A working 1fe instance with at least one widget, administrative access to cloud infrastructure, and understanding of CI/CD concepts. + +## What We're Building + +**[🏢 Production Hosting](#🏢-production-hosting)** - Scalable hosting service for your 1fe instance (~45 min) +**[☁️ CDN Setup](#☁️-cdn-setup)** - Content delivery network for widget bundles (~30 min) +**[📦 NPM Registry](#📦-npm-registry)** - Private package management and distribution (~20 min) +**[🗄 Configuration Service](#🗄-configuration-service)** - Dynamic settings and metadata management (~25 min) +**[🔄 CI/CD Pipeline](#🔄-cicd-pipeline)** - Automated deployments and rollbacks (~60 min) + +Let's start building production infrastructure. + +--- + +## 🏢 Production Hosting + +Set up production hosting for your 1fe application shell. This will handle user traffic and serve your application globally with proper scaling and monitoring. + +### Setup Production Hosting + +Follow our detailed hosting setup guide: + +**[→ Hosting Service Setup Guide](/how-to-guides/infrastructure-setup/hosting-setup/)** + +This covers: + +
+ +- Production hosting service (Azure Web App, AWS, etc.) +- Environment variables for production configuration +- SSL/TLS security and monitoring + +
+ +### Verify Setup + +After completing the setup: + +
+ +- Your 1fe instance loads from the production URL +- SSL certificate is properly configured +- Environment variables are accessible +- Monitoring is collecting logs and metrics + +
+ +--- + +## ☁️ CDN Setup + +You need a Content Delivery Network (CDN) to efficiently deliver your widget bundles to users worldwide with fast loading times and global caching. + +### What You'll Set Up + +
+ +- **Global CDN infrastructure** for widget bundle delivery +- **Caching policies** and compression settings +- **SSL/TLS security** for content delivery +- **Cache invalidation** for deploying updates + +
+ +### Complete Setup Guide + +Follow our detailed step-by-step guide for CDN setup: + +**[→ CDN Setup Guide](/how-to-guides/infrastructure-setup/cdn-setup/)** + +### Verification + +After completing the setup, verify: + +
+ +- Widget bundles load quickly from global CDN +- Caching policies are working correctly +- SSL certificates are properly configured +- Cache invalidation works for updates + +
+ +### Key Benefits + +**Performance**: Faster loading times for users worldwide +**Scalability**: Handle traffic spikes automatically +**Reliability**: Redundant infrastructure reduces downtime +**Cost Efficiency**: Reduced bandwidth costs from origin servers + +--- + +## 📦 NPM Registry + +A private NPM registry is essential for managing your 1fe widget packages securely and efficiently in a production environment. + +### What You'll Set Up + +
+ +- **Private NPM registry** for internal widget packages +- **Access controls** and authentication +- **CI/CD integration** for automated publishing +- **Package versioning** with changesets + +
+ +### Complete Setup Guide + +Follow our detailed step-by-step guide for NPM registry setup: + +**[→ NPM Registry Setup Guide](/how-to-guides/infrastructure-setup/npm-registry-setup/)** + +### Verification + +After completing the setup, verify: + +
+ +- Widgets can be published to private registry +- Access controls are working properly +- CI/CD pipeline can authenticate and publish +- Package versioning follows organization standards + +
+ +### Registry Benefits + +**Security**: Keep internal packages private and secure +**Control**: Manage access and permissions centrally +**Performance**: Faster package installation for teams +**Compliance**: Meet enterprise security requirements + +--- + +## 🗄 Configuration Service + +1fe requires a configuration service to manage **widget metadata** including version information, deployment status, and dependencies without code changes. + +### What You'll Set Up + +
+ +- **Configuration service** (Azure App Configuration, AWS Parameter Store, etc.) +- **Environment-specific configurations** for different deployment stages +- **Live configuration updates** without application restarts +- **Version management** for widget deployments + +
+ +### Complete Setup Guide + +Follow our detailed step-by-step guide for configuration service setup: + +**[→ Configuration Service Setup Guide](/how-to-guides/infrastructure-setup/configuration-setup/)** + +### Configuration Structure + +**Widget Versions** (`widget-versions.json`): + +```json +[ + { + "widgetId": "@company/user-dashboard", + "version": "1.2.3" + }, + { + "widgetId": "@company/analytics-widget", + "version": "2.1.0" + } +] +``` + +**Live Configuration** (`live.json`): + +```json +{ + "libraries": { + "basePrefix": "https://cdn.company.com/libs/" + }, + "widgets": { + "basePrefix": "https://cdn.company.com/widgets/", + "configs": [ + { + "widgetId": "@company/user-dashboard", + "plugin": { + "enabled": true, + "route": "/dashboard" + } + } + ] + } +} +``` + +### Verification + +After completing the setup, verify: + +
+ +- Configuration service responds correctly +- Environment-specific configs load properly +- Widget versions update without restarts +- Configuration changes deploy automatically + +
+ +### Configuration Benefits + +**Dynamic Updates**: Change widget versions without code deployment +**Environment Management**: Separate configs for dev/staging/prod +**Feature Flags**: Enable/disable widgets dynamically +**Rollback Capability**: Quick revert to previous configurations + +--- + +## 🔄 CI/CD Pipeline + +1fe uses a centralized CI/CD system to manage deployments across all widgets with automated testing, building, and deployment processes. + +### What You'll Set Up + +
+ +- **Automated build pipelines** for your 1fe instance and widgets +- **Multi-environment deployment** with approval workflows +- **Automated rollback capabilities** for quick issue resolution +- **Testing automation** and quality gates + +
+ +### Complete Setup Guide + +Follow our detailed step-by-step guide for CI/CD pipeline setup: + +**[→ CI/CD Pipeline Setup Guide](/how-to-guides/infrastructure-setup/project-setup/)** + +### Pipeline Architecture + +**1fe Instance Pipeline**: + +```yaml +# .github/workflows/1fe-instance.yml +name: Deploy 1fe Instance +on: + push: + branches: [main] +jobs: + build-and-deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: "22" + - run: yarn install + - run: yarn build + - run: yarn test + - name: Deploy to staging + run: # Deploy commands + - name: Deploy to production + if: github.ref == 'refs/heads/main' + run: # Production deploy commands +``` + +**Widget Pipeline**: + +```yaml +# .github/workflows/widget.yml +name: Deploy Widget +on: + push: + paths: ["widgets/**"] +jobs: + build-widget: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Build widget + run: yarn build:widget + - name: Publish to CDN + run: # Upload to CDN + - name: Update configuration + run: # Update widget versions +``` + +### Verification + +After completing the setup, verify: + +
+ +- Pipelines trigger on code changes +- Automated tests run successfully +- Deployments work across environments +- Rollback mechanisms function properly + +
+ +### Pipeline Benefits + +**Automation**: Reduce manual deployment errors +**Quality**: Automated testing and validation +**Speed**: Faster deployment cycles +**Reliability**: Consistent deployment processes +**Visibility**: Clear deployment status and history + +### Advanced Features + +**Blue-Green Deployments**: Zero-downtime deployments +**Canary Releases**: Gradual rollout to users +**Feature Flags**: Toggle features without deployment +**Automated Rollbacks**: Quick recovery from issues + +--- + +## 🎉 Congratulations! Production Infrastructure Complete! + +You've successfully set up enterprise-grade production infrastructure for your 1fe instance! Your organization now has a robust, scalable platform for micro-frontend development. + +### What You've Accomplished + +
+ +- ✅ **Production-ready hosting environment** with proper scaling and monitoring +- ✅ **Global CDN infrastructure** for efficient widget bundle delivery +- ✅ **Private NPM registry** for secure package management +- ✅ **Configuration service** for dynamic settings management +- ✅ **Automated CI/CD pipeline** for seamless deployments and rollbacks + +
+ +### Production Architecture Overview + +Your 1fe instance now has: + +**Infrastructure Layer**: + +
+ +- Scalable hosting (Azure/AWS/GCP) +- Global CDN for widget delivery +- Private NPM registry for packages + +
+ +**Configuration Layer**: + +
+ +- Dynamic configuration service +- Environment-specific settings +- Live widget version management + +
+ +**Deployment Layer**: + +
+ +- Automated CI/CD pipelines +- Multi-environment deployment +- Rollback capabilities + +
+ +### What's Next? + +**For Operational Excellence**: + +
+ +- **Monitoring & Alerting**: Set up comprehensive monitoring for your infrastructure +- **Security Hardening**: Implement additional security measures and compliance +- **Performance Optimization**: Fine-tune performance and scaling policies +- **Disaster Recovery**: Establish backup and recovery procedures + +
+ +**For Team Enablement**: + +
+ +- **Developer Onboarding**: Create guides for teams to deploy widgets +- **Best Practices**: Establish coding standards and deployment workflows +- **Training Programs**: Educate teams on 1fe development patterns +- **Support Processes**: Set up help desk and troubleshooting resources + +
+ +**For Advanced Features**: + +
+ +- **[Authentication Integration](/how-to-guides/authentication/)** - Implement SSO and user management +- **[Custom Shell Components](/how-to-guides/override-shell-components/)** - Customize the platform experience +- **[Advanced Monitoring](/how-to-guides/monitoring/)** - Set up detailed analytics and performance tracking +- **[Custom Utilities](/how-to-guides/custom-utilities/)** - Build organization-specific platform utilities + +
+ +### Success Metrics + +Monitor these key indicators for your production 1fe instance: + +**Performance**: + +
+ +- Widget load times < 2 seconds +- 99.9% uptime across all environments +- CDN cache hit ratio > 90% + +
+ +**Developer Experience**: + +
+ +- Deployment time < 10 minutes +- Zero-downtime deployments +- Automated rollback success rate > 95% + +
+ +**Business Value**: + +
+ +- Reduced development cycle time +- Increased team independence +- Improved feature delivery velocity + +
+ +**Your 1fe instance is now ready to support multiple development teams with enterprise-grade infrastructure. Welcome to production-ready micro-frontend development!** 🚀 diff --git a/src/content/docs/tutorials/setup-and-deploy-1fe-poc.mdx b/src/content/docs/tutorials/setup-and-deploy-1fe-poc.mdx new file mode 100644 index 0000000..be47038 --- /dev/null +++ b/src/content/docs/tutorials/setup-and-deploy-1fe-poc.mdx @@ -0,0 +1,443 @@ +--- +title: "Setup and Deploy 1fe POC" +description: Create a 1fe instance, develop a widget, and deploy a proof of concept +sidebar: + order: 1 +--- + +import { FcOk } from "react-icons/fc"; + +Let's build a complete 1fe proof of concept. You'll create a local 1fe instance, develop a widget using the playground, and deploy everything to production. + +This tutorial is designed for platform teams evaluating [micro-frontend solutions](/learning/why-1fe/) for their organization. + +**Prerequisites:** Node.js 22+, yarn 4+, and access to deploy applications. + +## What We're Building + +**[🔧 Create Your 1fe Instance](#🔧-create-your-1fe-instance)** - Set up a local 1fe instance from scratch +**[🛠️ Develop Your First Widget](#🛠️-develop-your-first-widget)** - Create and develop a widget using the playground +**[🚀 Deploy Your Proof of Concept](#🚀-deploy-your-proof-of-concept)** - Deploy your instance to a production-like environment + +Let's start building. + +--- + +## 🔧 Create Your 1fe Instance + +Let's create your 1fe instance from scratch. A [1fe instance](/learning/what-is-1fe/) is a micro-frontend platform that hosts independent widgets. + +**1. Scaffold a starter application:** + +```bash +npx @1fe/create-1fe-app my-1fe-poc +``` + +**2. Clone the widget starter kit:** + +```bash +git clone https://github.com/docusign/1fe-widget-starter-kit.git +``` + +**3. Set up both repositories:** + +```bash +# Build the 1fe instance +cd my-1fe-poc +yarn && yarn build + +# Set up the widget starter kit +cd ../1fe-widget-starter-kit +yarn +``` + +### Start Development Servers + +**4. Run the 1fe instance:** + +```bash +cd my-1fe-poc +yarn dev +``` + +Your instance is now running at [http://localhost:3000](http://localhost:3000). + +**5. Run the widget development server:** + +```bash +cd 1fe-widget-starter-kit +yarn dev +``` + +This opens the [widget playground](http://localhost:3001/playground?widgetUrl=http%3A%2F%2F127.0.0.1%3A8080%2Fjs%2F1fe-bundle.js) where you can develop and test widgets. + +You now have a complete 1fe development environment running locally! + +--- + +## 🛠️ Develop Your First Widget + +Great! You now have a working 1fe instance. Let's dive into the development experience by creating and customizing widgets. + +### Explore the Local 1fe Instance + +**Test the sample widgets:** + +1. **Visit `http://localhost:3001/widget-starter-kit/utils` to view the example starter plugin** +2. **Click the button `utils.context.get`** + ![Example child widget](./assets/example-child-widget.png) +3. **What just happened?** + - 1fe loaded and rendered the plugin tied to the `/widget-starter-kit` route + - When `utils.context.get` was clicked, the plugin loaded a child widget via [platform utilities](/reference/platform-utilities/overview/) + +:::tip[The Magic Behind the Scenes] +1fe loads the latest widget bundles and assets from a CDN, enabling dynamic loading so your widgets can update independently without touching the main app! [Discover how this magic works](/learning/externalized-libraries/). +::: + +### Override Widget with Your Local Plugin + +Let's override the example plugin to use our plugin running locally. + +1. **If not already running, run `yarn dev` in `1fe-widget-starter-kit/`** + + ```bash + cd 1fe-widget-starter-kit + yarn dev + ``` + +2. **Visit `http://localhost:3001/widget-starter-kit` and click the `{...}` button at the bottom right corner of the screen** + ![Import map overrides button showing three dots in brackets](./assets/three-dots.png) + +3. **Search for `@1fe/widget-starter-kit` within the shelf and select the matching module** + ![Import map shelf](./assets/import-map-shelf.png) + +4. **In the `Override URL` field, enter `http://localhost:8080/js/1fe-bundle.js` and click `Apply override`** + ![Import map override modal](./assets/override-modal.png) + +5. **Make changes to your widget and observe the changes in the browser** + +### Customize Your 1fe Instance + +Now let's look at how to host your plugin locally so it shows up by default in the 1fe instance. + +**Build plugin assets:** + +1. **Make any content change to `1fe-widget-starter-kit/src`** + + ```tsx title="1fe-widget-starter-kit/src/app1.tsx" + 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 = (props) => { + useEffect(() => { + platformProps.utils.appLoadTime.end(); + console.log("Hello from app1!"); + }, []); + + return ; + }; + + export default withProvider(RootWrapper); + ``` + +2. **Build the plugin within `1fe-widget-starter-kit` directory** + :::caution + **Keep your 1fe instance running in the background**. 1fe CLI will need the development server for the build process. + ::: + + ```bash + cd 1fe-widget-starter-kit + yarn build:widget + ``` + + ![dist folder contents](./assets/example-plugin-dist.png) + +**Setup the playground widget:** + +1. **Fork the [1fe-playground](https://github.com/docusign/1fe-playground) repository to your GitHub account** + + ```bash + git clone https://github.com//1fe-playground.git + cd 1fe-playground + ``` + +2. **Install dependencies and build the widget:** + ```bash + yarn install + yarn build:widget + ``` + +**Host the widgets locally:** + +1. Fork the [mock-cdn-assets](https://github.com/docusign/mock-cdn-assets/tree/main) repository +2. Create a new directory within `integration/widgets/@1fe/widget-starter-kit` of your forked cdn repo. The directory name should be the version from the package.json of the widget-starter-kit repository (e.g `1.0.2`) +3. Upload the contents of the `1fe-widget-starter-kit/dist/` directory to the new directory +4. Create a new directory within `integration/widgets/@1fe/playground` of your forked cdn repo. The directory name should be the version from the package.json of the playground repository (e.g `1.0.50`) +5. Upload the contents of the `1fe-playground/dist/` directory to the playground directory. Following is an image which showcases what the directory structure will look like after you have moved the code over: + ![dist folder assets copied to CDN](./assets/example-plugin-cdn-assets.png) +6. Serve them locally using the serve package: + ```bash + npx serve -C + ``` + +**Use the new widget assets in our 1fe instance:** + +One of the key features of 1fe is the ability to dynamically load widgets and plugins via [Live Configurations](/learning/live-configurations). Let's take advantage of these configurations. + +**Update widget-versions.json:** + +Create `integration/configs/widget-versions.json` file within your forked mock-cdn-assets repository: + +```json title="widget-versions.json" +[ + { + "widgetId": "@1fe/playground", + "version": "" + }, + { + "widgetId": "@1fe/widget-starter-kit", + "version": "" + } +] +``` + +**Update live.json:** + +Locate `integration/configs/live.json` within your forked mock-cdn-assets repository and make the following changes: + +```diff title="live.json" +{ ++ "libraries": { ++ "basePrefix": "http://localhost:3000/integration/libs/" ++ }, + "widgets": { ++ "basePrefix": "http://localhost:3000/integration/widgets/", + "configs": [ + { + "widgetId": "@1fe/playground", + "plugin": { + "enabled": true, + "route": "/widget-starter-kit" + } + }, +- { +- "widgetId": "@1fe/sample-widget", +- "plugin": { +- "enabled": true, +- "route": "/sample-widget" +- } +- }, +- { +- "widgetId": "@1fe/sample-widget-with-auth", +- "plugin": { +- "enabled": true, +- "route": "/sample-widget-with-auth", +- "auth": { +- "authenticationType": "required" +- } +- } +- } + ] + } +} +``` + +**Point your local 1fe instance to the new CDN assets:** + +Update the `src/config/ecosystem-configs.ts` file: + +```tsx title="src/config/ecosystem-configs.ts" +// ... +export const configManagement: OneFEConfigManagement = { + widgetVersions: { + url: `http://localhost:3000/integration/configs/widget-versions.json`, + }, + libraryVersions: { + url: `http://localhost:3000/integration/configs/lib-versions.json`, + }, + dynamicConfigs: { + url: `http://localhost:3000/integration/configs/live.json`, + }, + refreshMs: 30 * 1000, +}; +``` + +Navigate to [starter kit locally](http://localhost:3001/widget-starter-kit/utils) and check the console for the message "Hello from app1!" to confirm that your changes are being reflected. + +##### Tada! + +![Example plugin change](./assets/example-plugin-change.png) + +:::note[CSP Gone Wrong!] +If you refresh the page and see Content Security Policy errors blocking you from loading assets, you need to update the CSP settings in the 1fe instance (`src/csp-configs.ts`) to allow them (`http://localhost:3000/`). +::: + +You now have a fully functional local 1fe instance with custom widgets! + +--- + +## 🚀 Deploy Your Proof of Concept + +Perfect! You've set up your 1fe instance and experienced the development workflow. Let's deploy your proof of concept to production to create a live demo for stakeholders. + +:::caution +**This is a POC deployment guide!** We're using public tooling to get something on the internet quickly. For production environments with proper CDN infrastructure, CI/CD pipelines, and robust hosting, visit our [productionization guide](/tutorials/productionize-your-1fe-instance/). +::: + +### Setup Required GitHub Repositories + +You need two GitHub repositories: + +**CDN Assets Repository** - For the `mock-cdn-assets` that will hold our assets. We'll use JSDelivr to serve these assets. + +**1fe Instance Repository** - For your 1fe instance that will be used to deploy your 1fe instance. + +### ☁️ Deploy Assets to CDN + +**Configure the 1fe instance first:** + +Let's assume you're going to use a git tag for your CDN assets like `v1.0.2`. Use `` to refer to this tag in the rest of this guide. + +1. **Point your 1fe instance to the new CDN assets for live configurations:** + + ```tsx title="src/config/ecosystem-configs.ts" + // ... + export const configManagement: OneFEConfigManagement = { + widgetVersions: { + url: `https://cdn.jsdelivr.net/gh//@/integration/configs/widget-versions.json`, + }, + libraryVersions: { + url: `https://cdn.jsdelivr.net/gh//@/integration/configs/lib-versions.json`, + }, + dynamicConfigs: { + url: `https://cdn.jsdelivr.net/gh//@/integration/configs/live.json`, + }, + refreshMs: 30 * 1000, + }; + ``` + +2. **Point your 1fe instance to the new CDN assets for critical libraries:** + + ```tsx title="src/config/ecosystem-configs.ts" + // ... + const shellBundleUrl = + isLocal || SERVER_BUILD_NUMBER === "local" + ? `http://localhost:3001/js/bundle.js` + : `https://cdn.jsdelivr.net/gh//@/${ENVIRONMENT}/shell/${SERVER_BUILD_NUMBER}/js/bundle.js`; + + const importMapOverrideUrl = isProduction + ? `https://cdn.jsdelivr.net/gh//@/${ENVIRONMENT}/libs/@1fe/import-map-overrides/3.1.1/dist/import-map-overrides-api.js` + : `https://cdn.jsdelivr.net/gh//@/${ENVIRONMENT}/libs/@1fe/import-map-overrides/3.1.1/dist/import-map-overrides.js`; + + export const criticalLibUrls = { + importMapOverride: importMapOverrideUrl, + systemJS: `https://cdn.jsdelivr.net/gh//@/${ENVIRONMENT}/libs/systemjs/6.14.0/dist/system.min.js`, + systemJSAmd: `https://cdn.jsdelivr.net/gh//@/${ENVIRONMENT}/libs/systemjs/6.14.0/dist/extras/amd.min.js`, + shellBundleUrl, + }; + ``` + +3. **Update the CSP policy** in `src/csp-configs.ts` to allow jsdelivr domains (`https://cdn.jsdelivr.net`) + +4. **Check this into your 1fe instance repository** + +**Add the 1fe instance bundle to the CDN:** + +1. **Build the 1fe instance again using `yarn build`** +2. **Copy the bundle over to your `mock-cdn-assets` repository:** + ```bash + mkdir -p mock-cdn-assets/integration/shell// + cp -r my-1fe-poc/dist/public/ mock-cdn-assets/integration/shell// + ``` + +**Create and Push Tags for JSDelivr:** + +1. **Create and push a Git tag:** + + ```bash + cd mock-cdn-assets + git add . + git commit -m "Add 1fe assets for deployment" + git tag v1.0.2 # Use your chosen tag here + git push origin main + git push origin v1.0.2 # Push the tag to GitHub + ``` + +2. **Your assets are now publicly accessible via JSDelivr URLs** + +:::tip +**JSDelivr not reflecting your changes?** Try purging the cache at https://www.jsdelivr.com/tools/purge. Changes typically appear within a few minutes. +::: + +### Deploy 1fe Instance to Hosting Service + +Your 1fe instance is now ready to be deployed to a server. You can choose any hosting service capable of serving a Node.js Express app: + +| Service | Documentation | +| ---------------------------------------------------------------- | --------------------------------------------------------------------- | +| [Render](https://render.com/) | https://render.com/docs/deploy-node-express-app | +| [Heroku](https://www.heroku.com/) | https://devcenter.heroku.com/articles/deploying-nodejs | +| [Railway](https://railway.app/) | https://docs.railway.com/guides/express | +| [Azure](https://azure.microsoft.com/en-us/services/app-service/) | https://learn.microsoft.com/en-us/azure/app-service/quickstart-nodejs | + +**Quick start deployment links:** + +**Render:** `https://render.com/deploy?repo=` +**Heroku:** `https://www.heroku.com/deploy?template=` + +After deployment, you'll be able to access your 1fe instance at the URL provided by your hosting service! + +--- + +## 🎉 Congratulations! Tutorial Complete! + +You have successfully completed the entire 1fe proof of concept tutorial! You now have a live, working 1fe instance that demonstrates the complete development-to-deployment workflow. + +### What You've Accomplished + +
+ +- ✅ **Built a complete 1fe proof of concept** from scratch to production +- ✅ **Deployed to production** with CDN infrastructure and hosting +- ✅ **Experienced the full development workflow** from setup to deployment +- ✅ **Created a demonstrable example** to share with stakeholders +- ✅ **Understood 1fe's architecture and benefits** through hands-on experience + +
+ +### What's Next? + +**For Immediate Use:** + +
+ +- Share your POC with stakeholders and team members +- Demonstrate the development workflow you just experienced +- Evaluate 1fe's fit for your organization's needs + +
+ +**For Production Implementation:** + +
+ +- **[Productionize Your 1fe Instance](/tutorials/productionize-your-1fe-instance/)** - Transform your POC into enterprise-ready infrastructure +- **[Authentication Setup](/how-to-guides/authentication/)** - Implement proper user authentication +- **[Custom Utilities](/how-to-guides/custom-utilities/)** - Build platform-specific utilities for your teams + +
+ +**For Deeper Understanding:** + +
+ +- **[What is 1fe?](/learning/what-is-1fe/)** - Dive deeper into 1fe concepts and architecture +- **[Infrastructure Setup Guides](/how-to-guides/#infrastructure-setup)** - Solve specific implementation challenges +- **[1fe Server Reference](/reference/1fe-server-reference/)** - Access technical documentation and API references + +
+ +**You've successfully proven that 1fe can standardize your frontend development while maintaining team independence. Welcome to the 1fe community!** 🎊 diff --git a/src/custom-sidebar-behavior.js b/src/custom-sidebar-behavior.js new file mode 100644 index 0000000..79872de --- /dev/null +++ b/src/custom-sidebar-behavior.js @@ -0,0 +1,51 @@ +// Custom sidebar behavior for Starlight +// This script adds auto-focus to index pages and accordion-style folder collapsing + +document.addEventListener("DOMContentLoaded", function () { + // Wait for Starlight to fully initialize + setTimeout(initCustomSidebarBehavior, 100); +}); + +function initCustomSidebarBehavior() { + const sidebar = document.querySelector(".sidebar-content"); + if (!sidebar) return; + + // Find all collapsible groups (folders) in the sidebar + const groups = sidebar.querySelectorAll(".sidebar-content details"); + + groups.forEach((group) => { + const summary = group.querySelector("summary"); + if (!summary) return; + + summary.addEventListener("click", function (e) { + const isCurrentlyOpen = group.hasAttribute("open"); + + // If clicking to open this group + if (!isCurrentlyOpen) { + // Close all other groups (accordion behavior) + groups.forEach((otherGroup) => { + if (otherGroup !== group && otherGroup.hasAttribute("open")) { + otherGroup.removeAttribute("open"); + } + }); + + // Auto-navigate to index page after a short delay + setTimeout(() => { + const indexLink = group.querySelector( + 'a[href*="/index"], a[href$="/"]' + ); + if (indexLink) { + // Check if we're not already on this page + if (window.location.pathname !== indexLink.getAttribute("href")) { + window.location.href = indexLink.getAttribute("href"); + } + } + }, 150); // Small delay to allow the expansion animation + } + }); + }); +} + +// Re-initialize when navigating between pages (for SPA behavior) +document.addEventListener("astro:page-load", initCustomSidebarBehavior); + diff --git a/src/styles/custom-sidebar.css b/src/styles/custom-sidebar.css new file mode 100644 index 0000000..6b9e073 --- /dev/null +++ b/src/styles/custom-sidebar.css @@ -0,0 +1,32 @@ +/* Custom sidebar styles for improved accordion behavior */ + +/* Smooth transitions for sidebar groups */ +.sidebar-content details { + transition: all 0.2s ease-in-out; +} + +/* Improved visual feedback for collapsible groups */ +.sidebar-content details[open] > summary { + font-weight: 600; +} + +/* Smooth animation for group content */ +.sidebar-content details > div { + transition: all 0.15s ease-in-out; +} + +/* Visual indication of active/focused group */ +.sidebar-content details:focus-within > summary { + background-color: var(--sl-color-accent-low); + border-radius: 4px; +} + +/* Ensure only one group appears "active" at a time */ +.sidebar-content details:not([open]) > summary { + opacity: 0.8; +} + +.sidebar-content details[open] > summary { + opacity: 1; +} + From 02336b4b72d8e9d50cba1bbf421489bb3b76b340 Mon Sep 17 00:00:00 2001 From: Mohit Khatri Date: Mon, 25 Aug 2025 11:19:28 -0700 Subject: [PATCH 2/3] Remove custom sidebar behavior files - Deleted public/custom-sidebar-behavior.js - Deleted public/custom-sidebar.css - Deleted src/custom-sidebar-behavior.js - Deleted src/styles/custom-sidebar.css Preparing branch for merge to main with clean tutorial consolidation. --- public/custom-sidebar-behavior.js | 138 ------------------------------ public/custom-sidebar.css | 41 --------- src/custom-sidebar-behavior.js | 51 ----------- src/styles/custom-sidebar.css | 32 ------- 4 files changed, 262 deletions(-) delete mode 100644 public/custom-sidebar-behavior.js delete mode 100644 public/custom-sidebar.css delete mode 100644 src/custom-sidebar-behavior.js delete mode 100644 src/styles/custom-sidebar.css diff --git a/public/custom-sidebar-behavior.js b/public/custom-sidebar-behavior.js deleted file mode 100644 index 0acee64..0000000 --- a/public/custom-sidebar-behavior.js +++ /dev/null @@ -1,138 +0,0 @@ -// Custom sidebar behavior for Starlight -// Adds auto-focus to index pages when opening folders - -(function () { - "use strict"; - - let isInitialized = false; - let processingClick = false; // Prevent infinite loops - - function initCustomSidebarBehavior() { - if (isInitialized) return; - - // Try multiple selectors to find the sidebar - const sidebar = - document.querySelector(".sidebar-content") || - document.querySelector("[data-sidebar]") || - document.querySelector(".sidebar") || - document.querySelector("nav[aria-label*='Sidebar']") || - document.querySelector("aside"); - - if (!sidebar) { - console.log("Sidebar not found, retrying..."); - // Only retry a few times to prevent infinite retries - setTimeout(initCustomSidebarBehavior, 500); - return; - } - - // Find all collapsible groups (folders) in the sidebar - let groups = sidebar.querySelectorAll("details"); - - // If no details found, try looking in the entire document - if (groups.length === 0) { - groups = document.querySelectorAll("details"); - } - - if (groups.length === 0) { - console.log("No collapsible groups found"); - return; - } - - console.log(`Found ${groups.length} sidebar groups`); - - groups.forEach((group, index) => { - const summary = group.querySelector("summary"); - if (!summary) return; - - // Add click listener without cloning (which was causing issues) - summary.addEventListener("click", function (e) { - if (processingClick) return; // Prevent infinite loops - - const isCurrentlyOpen = group.hasAttribute("open"); - console.log( - `Clicked group ${index}, currently open: ${isCurrentlyOpen}` - ); - - // If clicking to open this group - if (!isCurrentlyOpen) { - processingClick = true; - - // Auto-navigate to index page immediately - const links = group.querySelectorAll("a[href]"); - let indexLink = null; - - // Try to find index page - for (const link of links) { - const href = link.getAttribute("href"); - if ( - href && - (href.endsWith("/") || - href.includes("/index") || - href.split("/").pop() === "") - ) { - indexLink = link; - break; - } - } - - // If no specific index found, use the first link - if (!indexLink && links.length > 0) { - indexLink = links[0]; - } - - if (indexLink) { - const targetHref = indexLink.getAttribute("href"); - console.log(`Auto-navigating to: ${targetHref}`); - - // Check if we're not already on this page - if (window.location.pathname !== targetHref) { - window.location.href = targetHref; - } - } - - processingClick = false; - } else { - processingClick = false; - } - }); - }); - - isInitialized = true; - console.log("Custom sidebar behavior initialized successfully"); - } - - // Simple initialization - if (document.readyState === "loading") { - document.addEventListener("DOMContentLoaded", function () { - setTimeout(initCustomSidebarBehavior, 100); - }); - } else { - setTimeout(initCustomSidebarBehavior, 100); - } - - // Re-initialize on page changes (but with protection against loops) - document.addEventListener("astro:page-load", function () { - isInitialized = false; - processingClick = false; - setTimeout(initCustomSidebarBehavior, 200); - }); - - // Debug function - window.debugSidebar = function () { - const sidebar = - document.querySelector(".sidebar-content") || - document.querySelector("aside"); - const groups = document.querySelectorAll("details"); - console.log("Sidebar debug:"); - console.log("Sidebar element:", sidebar); - console.log("Found groups:", groups.length); - groups.forEach((group, i) => { - console.log( - `Group ${i}:`, - group.querySelector("summary")?.textContent, - "Open:", - group.hasAttribute("open") - ); - }); - }; -})(); diff --git a/public/custom-sidebar.css b/public/custom-sidebar.css deleted file mode 100644 index b83c555..0000000 --- a/public/custom-sidebar.css +++ /dev/null @@ -1,41 +0,0 @@ -/* Custom sidebar styles for improved accordion behavior */ - -/* Smooth transitions for sidebar groups */ -.sidebar-content details, -aside details { - transition: all 0.2s ease-in-out; -} - -/* Improved visual feedback for collapsible groups */ -.sidebar-content details[open] > summary, -aside details[open] > summary { - font-weight: 600; -} - -/* Smooth animation for group content */ -.sidebar-content details > div, -aside details > div { - transition: all 0.15s ease-in-out; -} - -/* Visual indication of active/focused group */ -.sidebar-content details:focus-within > summary, -aside details:focus-within > summary { - background-color: var(--sl-color-accent-low); - border-radius: 4px; -} - -/* Visual feedback for open groups */ -.sidebar-content details[open] > summary, -aside details[open] > summary { - font-weight: 600; -} - -/* Debug styles - remove these in production */ -.debug-sidebar details { - border: 1px solid red !important; -} - -.debug-sidebar details[open] { - border-color: green !important; -} diff --git a/src/custom-sidebar-behavior.js b/src/custom-sidebar-behavior.js deleted file mode 100644 index 79872de..0000000 --- a/src/custom-sidebar-behavior.js +++ /dev/null @@ -1,51 +0,0 @@ -// Custom sidebar behavior for Starlight -// This script adds auto-focus to index pages and accordion-style folder collapsing - -document.addEventListener("DOMContentLoaded", function () { - // Wait for Starlight to fully initialize - setTimeout(initCustomSidebarBehavior, 100); -}); - -function initCustomSidebarBehavior() { - const sidebar = document.querySelector(".sidebar-content"); - if (!sidebar) return; - - // Find all collapsible groups (folders) in the sidebar - const groups = sidebar.querySelectorAll(".sidebar-content details"); - - groups.forEach((group) => { - const summary = group.querySelector("summary"); - if (!summary) return; - - summary.addEventListener("click", function (e) { - const isCurrentlyOpen = group.hasAttribute("open"); - - // If clicking to open this group - if (!isCurrentlyOpen) { - // Close all other groups (accordion behavior) - groups.forEach((otherGroup) => { - if (otherGroup !== group && otherGroup.hasAttribute("open")) { - otherGroup.removeAttribute("open"); - } - }); - - // Auto-navigate to index page after a short delay - setTimeout(() => { - const indexLink = group.querySelector( - 'a[href*="/index"], a[href$="/"]' - ); - if (indexLink) { - // Check if we're not already on this page - if (window.location.pathname !== indexLink.getAttribute("href")) { - window.location.href = indexLink.getAttribute("href"); - } - } - }, 150); // Small delay to allow the expansion animation - } - }); - }); -} - -// Re-initialize when navigating between pages (for SPA behavior) -document.addEventListener("astro:page-load", initCustomSidebarBehavior); - diff --git a/src/styles/custom-sidebar.css b/src/styles/custom-sidebar.css deleted file mode 100644 index 6b9e073..0000000 --- a/src/styles/custom-sidebar.css +++ /dev/null @@ -1,32 +0,0 @@ -/* Custom sidebar styles for improved accordion behavior */ - -/* Smooth transitions for sidebar groups */ -.sidebar-content details { - transition: all 0.2s ease-in-out; -} - -/* Improved visual feedback for collapsible groups */ -.sidebar-content details[open] > summary { - font-weight: 600; -} - -/* Smooth animation for group content */ -.sidebar-content details > div { - transition: all 0.15s ease-in-out; -} - -/* Visual indication of active/focused group */ -.sidebar-content details:focus-within > summary { - background-color: var(--sl-color-accent-low); - border-radius: 4px; -} - -/* Ensure only one group appears "active" at a time */ -.sidebar-content details:not([open]) > summary { - opacity: 0.8; -} - -.sidebar-content details[open] > summary { - opacity: 1; -} - From 392e2d9867e9d42d0a1655d1df55f98947ac27f5 Mon Sep 17 00:00:00 2001 From: Mohit Khatri Date: Mon, 25 Aug 2025 11:23:11 -0700 Subject: [PATCH 3/3] Removing changes so the PR isn't that complicated. --- config-utils/sidebar.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/config-utils/sidebar.ts b/config-utils/sidebar.ts index 3064a34..c970dec 100644 --- a/config-utils/sidebar.ts +++ b/config-utils/sidebar.ts @@ -3,25 +3,36 @@ export const sidebarConfig = [ label: "Start Here", autogenerate: { directory: "start-here" }, collapsed: true, + // attrs: { style: "text-transform: 'capitalized'" }, }, { label: "Tutorials", autogenerate: { directory: "tutorials" }, collapsed: true, + // attrs: { style: "text-transform: 'capitalized'" }, }, { label: "Learning", autogenerate: { directory: "learning" }, collapsed: true, + // attrs: { style: "text-transform: 'capitalized'" }, }, { label: "How-to Guides", autogenerate: { directory: "how-to-guides" }, collapsed: true, + // attrs: { style: "text-transform: 'capitalized'" }, }, { label: "Reference", autogenerate: { directory: "reference" }, collapsed: true, + // attrs: { style: "text-transform: 'capitalized'" }, }, + // { + // label: 'Explanation', + // autogenerate: { directory: 'explanation' }, + // collapsed: true, + // // attrs: { style: "text-transform: 'capitalized'" }, + // } ];