CINXE.COM

Build your own edge computing app - DEV Community

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Build your own edge computing app - DEV Community</title> <meta name="last-updated" content="2025-03-07 05:13:54 UTC"> <meta name="user-signed-in" content="false"> <meta name="head-cached-at" content="1741324434"> <meta name="environment" content="production"> <link rel="stylesheet" href="https://assets.dev.to/assets/minimal-0a971eb021d2dc2b145c1df786e1b97f418c6b2d066e79802fea980acb513937.css" media="all" id="main-minimal-stylesheet" /> <link rel="stylesheet" href="https://assets.dev.to/assets/views-1c703342dce6eac414f19ca7fd07bcf83cbe44088659758144e52e7fa1e92dd3.css" media="all" id="main-views-stylesheet" /> <link rel="stylesheet" href="https://assets.dev.to/assets/crayons-0f2fc85bc159498f8ae6fba58c460e6deba863d02d59dfa994c1954976ddb6cc.css" media="all" id="main-crayons-stylesheet" /> <script src="https://assets.dev.to/assets/base-9d03ab7d486c2d56295834be6b93884d407a19243c89f39e58c14c9828e0a144.js" defer="defer"></script> <script src="https://assets.dev.to/assets/application-7258612fccf5d56314a6e4ad1898b4f818f474c4bb3485e302428d489a769a17.js" defer="defer"></script> <script src="https://assets.dev.to/assets/baseInitializers-b74902d56433062a87f5f1ce74769baf2a1a698772f46952b0ac72bc95c4abfd.js" defer="defer"></script> <script src="https://assets.dev.to/assets/baseTracking-b6bf73e5ee66633e151e7d5b7c6bbccedfa4c59e3615be97b98c4c0f543ddae7.js" defer="defer"></script> <meta name="search-script" content="https://assets.dev.to/assets/Search-1667defd820799649d6c3b2864f13786058190df703dd50ab75dce1ccb834c4b.js"> <link rel="canonical" href="https://dev.to/fastly/build-your-own-edge-computing-app-3cp2" /> <meta name="description" content="In this series we&#39;re learning about edge computing for the web. In the last two instalments we found... Tagged with webdev, learning, serverless, cloud."> <meta name="keywords" content="webdev, learning, serverless, cloud, software, coding, development, engineering, inclusive, community"> <meta property="og:type" content="article" /> <meta property="og:url" content="https://dev.to/fastly/build-your-own-edge-computing-app-3cp2" /> <meta property="og:title" content="Build your own edge computing app" /> <meta property="og:description" content="In this series we&#39;re learning about edge computing for the web. In the last two instalments we found..." /> <meta property="og:site_name" content="DEV Community" /> <meta name="twitter:site" content="@thepracticaldev"> <meta name="twitter:creator" content="@"> <meta name="twitter:title" content="Build your own edge computing app"> <meta name="twitter:description" content="In this series we&#39;re learning about edge computing for the web. In the last two instalments we found..."> <meta name="twitter:card" content="summary_large_image"> <meta name="twitter:widgets:new-embed-design" content="on"> <meta name="robots" content="max-snippet:-1, max-image-preview:large, max-video-preview:-1"> <meta property="og:image" content="https://media2.dev.to/dynamic/image/width=1000,height=500,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5u9sigsmcy9zzhg1vyxr.png" /> <meta name="twitter:image:src" content="https://media2.dev.to/dynamic/image/width=1000,height=500,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5u9sigsmcy9zzhg1vyxr.png"> <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"> <link rel="icon" type="image/x-icon" href="https://media2.dev.to/dynamic/image/width=32,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png" /> <link rel="apple-touch-icon" href="https://media2.dev.to/dynamic/image/width=180,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png"> <link rel="apple-touch-icon" sizes="152x152" href="https://media2.dev.to/dynamic/image/width=152,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png"> <link rel="apple-touch-icon" sizes="180x180" href="https://media2.dev.to/dynamic/image/width=180,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png"> <link rel="apple-touch-icon" sizes="167x167" href="https://media2.dev.to/dynamic/image/width=167,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png"> <link href="https://media2.dev.to/dynamic/image/width=192,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png" rel="icon" sizes="192x192" /> <link href="https://media2.dev.to/dynamic/image/width=128,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png" rel="icon" sizes="128x128" /> <meta name="apple-mobile-web-app-title" content="dev.to"> <meta name="application-name" content="dev.to"> <meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)"> <meta name="theme-color" content="#000000" media="(prefers-color-scheme: dark)"> <link rel="search" href="https://dev.to/open-search.xml" type="application/opensearchdescription+xml" title="DEV Community" /> <meta property="forem:name" content="DEV Community" /> <meta property="forem:logo" content="https://media2.dev.to/dynamic/image/width=512,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png" /> <meta property="forem:domain" content="dev.to" /> </head> <body class="sans-serif-article-body default-header" data-user-status="logged-out" data-community-name="DEV Community" data-subscription-icon="https://assets.dev.to/assets/subscription-icon-805dfa7ac7dd660f07ed8d654877270825b07a92a03841aa99a1093bd00431b2.png" data-locale="en" data-honeybadger-key="hbp_nqu4Y66HuEKlD6YRGssZuRQnPOjDm50J8Zkr" data-deployed-at="2025-03-06T22:08:34Z" data-latest-commit-id="fa013ee4ca85ded597dbd0052d239f306be73d25" data-ga-tracking="UA-71991109-1" data-cookie-banner-user-context="logged_out_only" data-cookie-banner-platform-context="off" data-algolia-id="PRSOBFP46H" data-algolia-search-key="9aa7d31610cba78851c9b1f63776a9dd" data-algolia-display="true" data-dynamic-url-component="bb-2" data-ga4-tracking-id="G-TYEM8Y3JN3"> <script> if (navigator.userAgent === 'ForemWebView/1' || window.frameElement) { document.body.classList.add("hidden-shell"); } </script> <link rel="stylesheet" href="https://assets.dev.to/assets/minimal-0a971eb021d2dc2b145c1df786e1b97f418c6b2d066e79802fea980acb513937.css" media="all" id="secondary-minimal-stylesheet" /> <link rel="stylesheet" href="https://assets.dev.to/assets/views-1c703342dce6eac414f19ca7fd07bcf83cbe44088659758144e52e7fa1e92dd3.css" media="all" id="secondary-views-stylesheet" /> <link rel="stylesheet" href="https://assets.dev.to/assets/crayons-0f2fc85bc159498f8ae6fba58c460e6deba863d02d59dfa994c1954976ddb6cc.css" media="all" id="secondary-crayons-stylesheet" /> <div id="body-styles"> <style> :root { --accent-brand-lighter-rgb: 80, 99, 301; --accent-brand-rgb: 59, 73, 223; --accent-brand-darker-rgb: 47, 58, 178; } </style> </div> <div id="audiocontent" data-podcast=""> </div> <div class="navigation-progress" id="navigation-progress"></div> <header id="topbar" class="crayons-header topbar print-hidden"> <span id="route-change-target" tabindex="-1"></span> <a href="#main-content" class="skip-content-link">Skip to content</a> <div class="crayons-header__container"> <span class="inline-block m:hidden "> <button class="c-btn c-btn--icon-alone js-hamburger-trigger mx-2"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" aria-labelledby="ad2gic2v196pet0h2apjkxi8gslpb5lh" class="crayons-icon"><title id="ad2gic2v196pet0h2apjkxi8gslpb5lh">Navigation menu</title> <path d="M3 4h18v2H3V4zm0 7h18v2H3v-2zm0 7h18v2H3v-2z"></path> </svg> </button> </span> <a href="/" class="site-logo" aria-label="DEV Community Home"> <img class="site-logo__img" src="https://media2.dev.to/dynamic/image/quality=100/https://dev-to-uploads.s3.amazonaws.com/uploads/logos/resized_logo_UQww2soKuUsjaOGNB38o.png" style="aspect-ratio: 10 / 8" alt="DEV Community"> </a> <div class="crayons-header--search js-search-form" id="header-search"> <form accept-charset="UTF-8" method="get" action="/search" role="search"> <div class="crayons-fields crayons-fields--horizontal"> <div class="crayons-field flex-1 relative"> <input id="search-input" class="crayons-header--search-input crayons-textfield js-search-input" type="text" id="nav-search" name="q" placeholder="Find related posts..." autocomplete="off" /> <button type="submit" aria-label="Search" class="c-btn c-btn--icon-alone absolute inset-px right-auto mt-0 py-0"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" aria-labelledby="a5h26iv47yvcoylnl5s08mt77gauaaye" aria-hidden="true" class="crayons-icon"><title id="a5h26iv47yvcoylnl5s08mt77gauaaye">Search</title> <path d="M18.031 16.617l4.283 4.282-1.415 1.415-4.282-4.283A8.96 8.96 0 0111 20c-4.968 0-9-4.032-9-9s4.032-9 9-9 9 4.032 9 9a8.96 8.96 0 01-1.969 5.617zm-2.006-.742A6.977 6.977 0 0018 11c0-3.868-3.133-7-7-7-3.868 0-7 3.132-7 7 0 3.867 3.132 7 7 7a6.977 6.977 0 004.875-1.975l.15-.15z"></path> </svg> </button> <a class="crayons-header--search-brand-indicator" href="https://www.algolia.com/developers/?utm_source=devto&utm_medium=referral" target="_blank" rel="noopener noreferrer"> Powered by <svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" width="24" height="24" viewBox="0 0 500 500.34" role="img" aria-labelledby="apop3plhveaku87jxgd8wzyg1bou7yd8" aria-hidden="true" class="crayons-icon"><title id="apop3plhveaku87jxgd8wzyg1bou7yd8">Search</title> <defs></defs><path class="cls-1" d="M250,0C113.38,0,2,110.16,.03,246.32c-2,138.29,110.19,252.87,248.49,253.67,42.71,.25,83.85-10.2,120.38-30.05,3.56-1.93,4.11-6.83,1.08-9.52l-23.39-20.74c-4.75-4.22-11.52-5.41-17.37-2.92-25.5,10.85-53.21,16.39-81.76,16.04-111.75-1.37-202.04-94.35-200.26-206.1,1.76-110.33,92.06-199.55,202.8-199.55h202.83V407.68l-115.08-102.25c-3.72-3.31-9.43-2.66-12.43,1.31-18.47,24.46-48.56,39.67-81.98,37.36-46.36-3.2-83.92-40.52-87.4-86.86-4.15-55.28,39.65-101.58,94.07-101.58,49.21,0,89.74,37.88,93.97,86.01,.38,4.28,2.31,8.28,5.53,11.13l29.97,26.57c3.4,3.01,8.8,1.17,9.63-3.3,2.16-11.55,2.92-23.6,2.07-35.95-4.83-70.39-61.84-127.01-132.26-131.35-80.73-4.98-148.23,58.18-150.37,137.35-2.09,77.15,61.12,143.66,138.28,145.36,32.21,.71,62.07-9.42,86.2-26.97l150.36,133.29c6.45,5.71,16.62,1.14,16.62-7.48V9.49C500,4.25,495.75,0,490.51,0H250Z"></path> </svg> Algolia </a> </div> </div> </form> </div> <div class="flex items-center h-100 ml-auto"> <div class="flex" id="authentication-top-nav-actions"> <span class="hidden m:block"> <a href="https://dev.to/enter" class="c-link c-link--block mr-2 whitespace-nowrap ml-auto" data-no-instant> Log in </a> </span> <a href="https://dev.to/enter?state=new-user" data-tracking-id="ca_top_nav" data-tracking-source="top_navbar" class="c-cta c-cta--branded whitespace-nowrap mr-2" data-no-instant> Create account </a> </div> </div> </div> </header> <div class="hamburger"> <div class="hamburger__content"> <header class="hamburger__content__header"> <h2 class="fs-l fw-bold flex-1 break-word lh-tight">DEV Community</h2> <button class="c-btn c-btn--icon-alone js-hamburger-trigger shrink-0" aria-label="Close"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" aria-labelledby="a7yk49vy4doq78kywznpthnoj3t3erz8" aria-hidden="true" class="crayons-icon c-btn__icon"><title id="a7yk49vy4doq78kywznpthnoj3t3erz8">Close</title><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636l4.95 4.95z"></path></svg> </button> </header> <div class="p-2 js-navigation-links-container" id="authentication-hamburger-actions"> </div> </div> <div class="hamburger__overlay js-hamburger-trigger"></div> </div> <div id="active-broadcast" class="broadcast-wrapper"></div> <div id="page-content" class="wrapper stories stories-show articletag-webdev articletag-learning articletag-serverless articletag-cloud articleuser-154099 articleorg-2298" data-current-page="stories-show"> <div id="page-content-inner" data-internal-nav="false"> <div id="page-route-change" class="screen-reader-only" aria-live="polite" aria-atomic="true"></div> <link rel="prefetch" href="/reactions?article_id=1994941"> <style> .html-variant-wrapper { display: none} </style> <script src="https://unpkg.com/@webcomponents/webcomponentsjs@2.2.10/webcomponents-loader.js" integrity="sha384-3HK5hxQbkFqOIxMbpROlRmRtYl2LBZ52t+tqcjzsmr9NJuOWQxl8RgQSyFvq2lhy" crossorigin="anonymous" defer></script> <script src="https://assets.dev.to/assets/webShare-0686f0b9ac40589694ef6ae6a6202c44119bc781c254f6cf6d52d8a008461156.js" defer="defer"></script> <script src="https://assets.dev.to/assets/articlePage-e91bed0487621b06608474cfabffa186165e1f43f05b24581203ccc21e7aa45d.js" defer="defer"></script> <script src="https://assets.dev.to/assets/commentDropdowns-7a28d130e5b78d38b30a9495a964003a66bd64fa455fc70b766d69cf06b9ba24.js" defer="defer"></script> <script type="application/ld+json"> {"@context":"http://schema.org","@type":"Article","mainEntityOfPage":{"@type":"WebPage","@id":"https://dev.to/fastly/build-your-own-edge-computing-app-3cp2"},"url":"https://dev.to/fastly/build-your-own-edge-computing-app-3cp2","image":["https://media2.dev.to/dynamic/image/width=1080,height=1080,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5u9sigsmcy9zzhg1vyxr.png","https://media2.dev.to/dynamic/image/width=1280,height=720,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5u9sigsmcy9zzhg1vyxr.png","https://media2.dev.to/dynamic/image/width=1600,height=900,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5u9sigsmcy9zzhg1vyxr.png"],"publisher":{"@context":"http://schema.org","@type":"Organization","name":"DEV Community","logo":{"@context":"http://schema.org","@type":"ImageObject","url":"https://media2.dev.to/dynamic/image/width=192,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png","width":"192","height":"192"}},"headline":"Build your own edge computing app","author":{"@context":"http://schema.org","@type":"Person","url":"https://dev.to/suesmith","name":"Sue Smith"},"datePublished":"2024-09-10T14:18:13Z","dateModified":"2024-12-17T17:36:31Z"} </script> <div class="crayons-layout crayons-layout--3-cols crayons-layout--article"> <aside class="crayons-layout__sidebar-left" aria-label="Article actions"> <div class="crayons-article-actions print-hidden"> <div class="crayons-article-actions__inner"> <div class="reaction-drawer__outer hoverdown" style=""> <button id="reaction-drawer-trigger" aria-label="reaction-drawer-trigger" aria-pressed="false" class="hoverdown-trigger crayons-reaction pseudo-reaction crayons-tooltip__activator relative"> <span class="crayons-reaction__icon crayons-reaction__icon--borderless crayons-reaction--like crayons-reaction__icon--inactive" style="width: 40px; height: 40px"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" role="img" aria-hidden="true" class="crayons-icon"> <g clip-path="url(#clip0_988_3276)"> <path d="M19 14V17H22V19H18.999L19 22H17L16.999 19H14V17H17V14H19ZM20.243 4.75698C22.505 7.02498 22.583 10.637 20.479 12.992L19.059 11.574C20.39 10.05 20.32 7.65998 18.827 6.16998C17.324 4.67098 14.907 4.60698 13.337 6.01698L12.002 7.21498L10.666 6.01798C9.09103 4.60598 6.67503 4.66798 5.17203 6.17198C3.68203 7.66198 3.60703 10.047 4.98003 11.623L13.412 20.069L12 21.485L3.52003 12.993C1.41603 10.637 1.49503 7.01898 3.75603 4.75698C6.02103 2.49298 9.64403 2.41698 12 4.52898C14.349 2.41998 17.979 2.48998 20.242 4.75698H20.243Z" fill="#525252"></path> </g> <defs> <clipPath id="clip0_988_3276"> <rect width="24" height="24" fill="white"></rect> </clipPath> </defs> </svg> </span> <span class="crayons-reaction__icon crayons-reaction__icon--borderless crayons-reaction__icon--active" style="width: 40px; height: 40px"> <img aria_hidden="true" height="24" width="24" src="https://assets.dev.to/assets/heart-plus-active-9ea3b22f2bc311281db911d416166c5f430636e76b15cd5df6b3b841d830eefa.svg" /> </span> <span class="crayons-reaction__count" id="reaction_total_count"> <span class="bg-base-40 opacity-25 p-2 inline-block radius-default"></span> </span> <span class="crayons-tooltip__content"> Add reaction </span> </button> <div class="reaction-drawer" aria-expanded="false"> <div class="reaction-drawer__container"> <button id="reaction-butt-like" name="Like" aria-label="Like" aria-pressed="false" class="crayons-reaction crayons-tooltip__activator relative pt-2 pr-2 pb-1 pl-2" data-category="like"> <span class="crayons-reaction__icon crayons-reaction__icon--inactive p-0"> <img aria_hidden="true" height="32" width="32" src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" /> </span> <span class="crayons-reaction__count" id="reaction-number-like"><span class="bg-base-40 opacity-25 p-2 inline-block radius-default"></span></span> <span data-testid="tooltip" class="crayons-tooltip__content"> Like </span> </button> <button id="reaction-butt-unicorn" name="Unicorn" aria-label="Unicorn" aria-pressed="false" class="crayons-reaction crayons-tooltip__activator relative pt-2 pr-2 pb-1 pl-2" data-category="unicorn"> <span class="crayons-reaction__icon crayons-reaction__icon--inactive p-0"> <img aria_hidden="true" height="32" width="32" src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" /> </span> <span class="crayons-reaction__count" id="reaction-number-unicorn"><span class="bg-base-40 opacity-25 p-2 inline-block radius-default"></span></span> <span data-testid="tooltip" class="crayons-tooltip__content"> Unicorn </span> </button> <button id="reaction-butt-exploding_head" name="Exploding Head" aria-label="Exploding Head" aria-pressed="false" class="crayons-reaction crayons-tooltip__activator relative pt-2 pr-2 pb-1 pl-2" data-category="exploding_head"> <span class="crayons-reaction__icon crayons-reaction__icon--inactive p-0"> <img aria_hidden="true" height="32" width="32" src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" /> </span> <span class="crayons-reaction__count" id="reaction-number-exploding_head"><span class="bg-base-40 opacity-25 p-2 inline-block radius-default"></span></span> <span data-testid="tooltip" class="crayons-tooltip__content"> Exploding Head </span> </button> <button id="reaction-butt-raised_hands" name="Raised Hands" aria-label="Raised Hands" aria-pressed="false" class="crayons-reaction crayons-tooltip__activator relative pt-2 pr-2 pb-1 pl-2" data-category="raised_hands"> <span class="crayons-reaction__icon crayons-reaction__icon--inactive p-0"> <img aria_hidden="true" height="32" width="32" src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" /> </span> <span class="crayons-reaction__count" id="reaction-number-raised_hands"><span class="bg-base-40 opacity-25 p-2 inline-block radius-default"></span></span> <span data-testid="tooltip" class="crayons-tooltip__content"> Raised Hands </span> </button> <button id="reaction-butt-fire" name="Fire" aria-label="Fire" aria-pressed="false" class="crayons-reaction crayons-tooltip__activator relative pt-2 pr-2 pb-1 pl-2" data-category="fire"> <span class="crayons-reaction__icon crayons-reaction__icon--inactive p-0"> <img aria_hidden="true" height="32" width="32" src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" /> </span> <span class="crayons-reaction__count" id="reaction-number-fire"><span class="bg-base-40 opacity-25 p-2 inline-block radius-default"></span></span> <span data-testid="tooltip" class="crayons-tooltip__content"> Fire </span> </button> </div> </div> </div> <button id="reaction-butt-comment" aria-label="Jump to Comments" aria-pressed="false" class="crayons-reaction crayons-reaction--comment crayons-tooltip__activator relative" data-category="comment"> <span class="crayons-reaction__icon crayons-reaction__icon--borderless crayons-reaction__icon--inactive"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" aria-hidden="true" class="crayons-icon"> <path d="M10 3h4a8 8 0 010 16v3.5c-5-2-12-5-12-11.5a8 8 0 018-8zm2 14h2a6 6 0 000-12h-4a6 6 0 00-6 6c0 3.61 2.462 5.966 8 8.48V17z"></path> </svg> </span> <span class="crayons-reaction__count" id="reaction-number-comment" data-count="2"> <span class="bg-base-40 opacity-25 p-2 inline-block radius-default"></span> </span> <span data-testid="tooltip" class="crayons-tooltip__content"> Jump to Comments </span> </button> <button id="reaction-butt-readinglist" aria-label="Add to reading list" aria-pressed="false" class="crayons-reaction crayons-reaction--readinglist crayons-tooltip__activator relative" data-category="readinglist"> <span class="crayons-reaction__icon crayons-reaction__icon--borderless crayons-reaction__icon--inactive"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" aria-hidden="true" class="crayons-icon"> <path d="M5 2h14a1 1 0 011 1v19.143a.5.5 0 01-.766.424L12 18.03l-7.234 4.536A.5.5 0 014 22.143V3a1 1 0 011-1zm13 2H6v15.432l6-3.761 6 3.761V4z"></path> </svg> </span> <span class="crayons-reaction__count" id="reaction-number-readinglist"><span class="bg-base-40 opacity-25 p-2 inline-block radius-default"></span></span> <span data-testid="tooltip" class="crayons-tooltip__content"> Save </span> </button> <button id="reaction-butt-boost" aria-label="Boost" aria-pressed="false" class="crayons-reaction crayons-reaction--boost crayons-tooltip__activator relative"> <span class="crayons-reaction__icon crayons-reaction__icon--borderless crayons-reaction__icon--inactive"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" role="img" aria-hidden="true" class="crayons-icon" width="24" height="24"> <path transform="translate(24,0) scale(-1,1)" d="M6 4H21C21.5523 4 22 4.44772 22 5V12H20V6H6V9L1 5L6 1V4ZM18 20H3C2.44772 20 2 19.5523 2 19V12H4V18H18V15L23 19L18 23V20Z"></path> </svg> </span> <span data-testid="tooltip" class="crayons-tooltip__content"> Boost </span> </button> <div class="only-sidebar-menu-item"> <div id="mod-actions-menu-btn-area" class="print-hidden trusted-visible-block align-center"> </div> </div> <div class="align-center m:relative"> <button id="article-show-more-button" aria-controls="article-show-more-dropdown" aria-expanded="false" aria-haspopup="true" class="dropbtn crayons-btn crayons-btn--ghost-dimmed crayons-btn--icon-rounded" aria-label="Share post options"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" role="img" aria-labelledby="aibrx08ql07jmtit177kydyd5pu5j0aq" aria-hidden="true" class="crayons-icon dropdown-icon"><title id="aibrx08ql07jmtit177kydyd5pu5j0aq">More...</title><path fill-rule="evenodd" clip-rule="evenodd" d="M7 12a2 2 0 11-4 0 2 2 0 014 0zm7 0a2 2 0 11-4 0 2 2 0 014 0zm5 2a2 2 0 100-4 2 2 0 000 4z"></path></svg> </button> <div id="article-show-more-dropdown" class="crayons-dropdown side-bar left-2 right-2 m:right-auto m:left-100 s:left-auto mb-1 m:mb-0 top-unset bottom-100 m:top-0 m:bottom-unset"> <div class="only-mobile-menu-item"> <button class="mod-actions-menu-btn crayons-link crayons-link--block w-100 bg-transparent border-0 fw-bold"> Moderate </button> </div> <div> <button id="copy-post-url-button" class="flex justify-between crayons-link crayons-link--block w-100 bg-transparent border-0" data-postUrl="https://dev.to/fastly/build-your-own-edge-computing-app-3cp2"> <span class="fw-bold">Copy link</span> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" id="article-copy-icon" role="img" aria-labelledby="ahqkiiuq0zu8xbdgdxugjeffgnfgf2li" aria-hidden="true" class="crayons-icon mx-2 shrink-0"><title id="ahqkiiuq0zu8xbdgdxugjeffgnfgf2li">Copy link</title> <path d="M7 6V3a1 1 0 011-1h12a1 1 0 011 1v14a1 1 0 01-1 1h-3v3c0 .552-.45 1-1.007 1H4.007A1 1 0 013 21l.003-14c0-.552.45-1 1.007-1H7zm2 0h8v10h2V4H9v2zm-2 5v2h6v-2H7zm0 4v2h6v-2H7z"></path> </svg> </button> <div id="article-copy-link-announcer" aria-live="polite" class="crayons-notice crayons-notice--success my-2 p-1" aria-live="polite" hidden>Copied to Clipboard</div> </div> <div class="Desktop-only"> <a target="_blank" class="crayons-link crayons-link--block" rel="noopener" href='https://twitter.com/intent/tweet?text=%22Build%20your%20own%20edge%20computing%20app%22%20by%20Sue%20Smith%20%23DEVCommunity%20https%3A%2F%2Fdev.to%2Ffastly%2Fbuild-your-own-edge-computing-app-3cp2'> Share to X </a> <a target="_blank" class="crayons-link crayons-link--block" rel="noopener" href="https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fdev.to%2Ffastly%2Fbuild-your-own-edge-computing-app-3cp2&title=Build%20your%20own%20edge%20computing%20app&summary=In%20this%20series%20we%27re%20learning%20about%20edge%20computing%20for%20the%20web.%20In%20the%20last%20two%20instalments%20we%20found...&source=DEV%20Community"> Share to LinkedIn </a> <a target="_blank" class="crayons-link crayons-link--block" rel="noopener" href="https://www.facebook.com/sharer.php?u=https%3A%2F%2Fdev.to%2Ffastly%2Fbuild-your-own-edge-computing-app-3cp2"> Share to Facebook </a> <a target="_blank" class="crayons-link crayons-link--block" rel="noopener" href="https://toot.kytta.dev/?text=https%3A%2F%2Fdev.to%2Ffastly%2Fbuild-your-own-edge-computing-app-3cp2"> Share to Mastodon </a> </div> <web-share-wrapper shareurl="https://dev.to/fastly/build-your-own-edge-computing-app-3cp2" sharetitle="Build your own edge computing app" sharetext="In this series we&#39;re learning about edge computing for the web. In the last two instalments we found..." template="web-share-button"> </web-share-wrapper> <template id="web-share-button"> <a href="#" class="dropdown-link-row crayons-link crayons-link--block">Share Post via...</a> </template> <a href="/report-abuse" class="crayons-link crayons-link--block">Report Abuse</a> </div> </div> </div> </div> </aside> <main id="main-content" class="crayons-layout__content grid gap-4"> <div class="article-wrapper"> <article class="crayons-card crayons-article mb-4" id="article-show-container" data-article-id="1994941" data-article-slug="build-your-own-edge-computing-app-3cp2" data-author-id="154099" data-author-name="Sue Smith" data-author-username="fastly" data-co-author-ids="" data-path="/fastly/build-your-own-edge-computing-app-3cp2" data-pin-path="/stories/feed/pinned_article" data-pinned-article-id="" data-published="true" data-scheduled="false" lang=en > <header class="crayons-article__header" id="main-title"> <a class="crayons-article__cover" href="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5u9sigsmcy9zzhg1vyxr.png"> <img src="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5u9sigsmcy9zzhg1vyxr.png" style="aspect-ratio: auto 1000 / 420;" width="1000" height="420" class="crayons-article__cover__image" alt="Cover image for Build your own edge computing app"> </a> <div class="crayons-article__header__meta"> <div class="flex s:items-start flex-col s:flex-row"> <div id="action-space" class="crayons-article__actions mb-4 s:mb-0 s:order-last"></div> <div class="flex flex-1 mb-5 items-start"> <div class="relative"> <a href="/fastly"><img src="https://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F2298%2F27608760-4be1-4e12-b054-b8a2748d978d.png" class="radius-default align-middle" width="40" height="40" alt="Fastly profile image"></a> <a href="/suesmith" class="absolute -right-2 -bottom-2 radius-full border border-solid border-2 border-base-inverted inline-flex"> <img class="radius-full align-middle" src="https://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F154099%2F9d185df0-7f11-45be-a0d9-a24997721513.jpg" width="24" height="24" alt="Sue Smith" /> </a> </div> <div class="pl-3 flex-1"> <a href="/suesmith" class="crayons-link fw-bold">Sue Smith</a> <span class="color-base-60"> for </span><a href="/fastly" class="crayons-link">Fastly</a> <p class="fs-xs color-base-60"> Posted on <time datetime="2024-09-10T14:18:13Z" class="date">Sep 10, 2024</time> &bull; Edited on <time datetime="2024-12-17T17:36:31Z" class="date">Dec 17, 2024</time> </p> </div> </div> </div> <div class="multiple_reactions_engagement"> <span class="reaction_engagement_like hidden"> <img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24" /> <span id="reaction_engagement_like_count">&nbsp;</span> </span> <span class="reaction_engagement_unicorn hidden"> <img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="24" height="24" /> <span id="reaction_engagement_unicorn_count">&nbsp;</span> </span> <span class="reaction_engagement_exploding_head hidden"> <img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="24" height="24" /> <span id="reaction_engagement_exploding_head_count">&nbsp;</span> </span> <span class="reaction_engagement_raised_hands hidden"> <img src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" width="24" height="24" /> <span id="reaction_engagement_raised_hands_count">&nbsp;</span> </span> <span class="reaction_engagement_fire hidden"> <img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="24" height="24" /> <span id="reaction_engagement_fire_count">&nbsp;</span> </span> </div> <h1 class=" fs-3xl m:fs-4xl l:fs-5xl fw-bold s:fw-heavy lh-tight mb-2 medium"> Build your own edge computing app </h1> <div class="spec__tags flex flex-wrap"> <a class="crayons-tag " style=" --tag-bg: rgba(86, 39, 101, 0.10); --tag-prefix: #562765; --tag-bg-hover: rgba(86, 39, 101, 0.10); --tag-prefix-hover: #562765; " href="/t/webdev"><span class="crayons-tag__prefix">#</span>webdev</a> <a class="crayons-tag " style=" --tag-bg: rgba(255, 102, 237, 0.10); --tag-prefix: #ff66ed; --tag-bg-hover: rgba(255, 102, 237, 0.10); --tag-prefix-hover: #ff66ed; " href="/t/learning"><span class="crayons-tag__prefix">#</span>learning</a> <a class="crayons-tag " style=" --tag-bg: rgba(28, 28, 28, 0.10); --tag-prefix: #1C1C1C; --tag-bg-hover: rgba(28, 28, 28, 0.10); --tag-prefix-hover: #1C1C1C; " href="/t/serverless"><span class="crayons-tag__prefix">#</span>serverless</a> <a class="crayons-tag " style=" --tag-bg: rgba(255, 153, 0, 0.10); --tag-prefix: #FF9900; --tag-bg-hover: rgba(255, 153, 0, 0.10); --tag-prefix-hover: #FF9900; " href="/t/cloud"><span class="crayons-tag__prefix">#</span>cloud</a> </div> </div> </header> <div class="crayons-article__main "> <div class="crayons-article__body text-styles spec__body" data-article-id="1994941" id="article-body"> <p>In this series we're learning about edge computing for the web. In the last two instalments we found out what and where the edge is:</p> <ul> <li><a href="https://dev.to/fastly/an-easy-intro-to-edge-computing-3ced">Part 1: An easy intro to edge computing</a></li> <li><a href="https://dev.to/fastly/where-is-the-edge-12j2">Part 2: Where is the edge?</a></li> </ul> <p>Now it's time to get your hands on your very own edge computing web app – and the cool part is you'll have it deployed in minutes without even downloading or installing anything onto your computer, because we're doing it in Glitch. 🎏</p> <p><iframe width="710" height="399" src="https://www.youtube.com/embed/MzXPaeTQGNU" allowfullscreen loading="lazy"> </iframe> </p> <h2> <a name="remix-the-glitch-website" href="#remix-the-glitch-website"> </a> Remix the Glitch website </h2> <p>We're using a simple demo website on Glitch that just has a single web page in it. </p> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F40qk6tyu678g0st29out.png" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F40qk6tyu678g0st29out.png" alt="Our website" loading="lazy" width="800" height="865"></a></p> <p>When we deploy it to Fastly, we're going to use the Compute platform to change the user experience for the website at the edge. Compute is going to let us run a serverless edge computing app on the Fastly network. The app will run in between the website host and our users, so it can change the request and response when people visit the site.</p> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdpg2eelgro71sz3ma8xv.png" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdpg2eelgro71sz3ma8xv.png" alt="Edge website" loading="lazy" width="800" height="875"></a></p> <p>We're keeping it basic to get started, but our Compute code will switch the website stylesheet and add some info about the user location. We could use a similar pattern to customize the site UX in other ways, like tailoring it to the user's location or preferences.</p> <p>Check out the demo:</p> <ul> <li><a href="https://learn-edge-computing.glitch.me" target="_blank" rel="noopener noreferrer">Glitch <em>origin</em> website</a></li> <li><a href="https://learn-edge-computing.edgecompute.app" target="_blank" rel="noopener noreferrer">Fastly edge deployed version</a></li> </ul> <p><strong>Go ahead and remix the site: <a href="https://glitch.com/~learn-edge-computing" target="_blank" rel="noopener noreferrer">~learn-edge-computing</a></strong></p> <p>Your own copy of the website will open in the Glitch editor in your browser. <em>Sign up / into Glitch if you want to keep the project.</em></p> <p>All of the steps are in the project <code>README</code> – make sure you use <strong>Preview</strong> &gt; <strong>Open preview pane</strong> to see your live site at its <code>glitch.me</code> address.</p> <h2> <a name="check-out-the-compute-code" href="#check-out-the-compute-code"> </a> Check out the Compute code </h2> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn7n8f8872qy5xg3c6wmw.png" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn7n8f8872qy5xg3c6wmw.png" alt="The Glitch project edge folder" loading="lazy" width="800" height="418"></a></p> <p>In your project, you'll find the code for your edge computing app in the <code>edge</code> folder. There are two files to pay attention to:</p> <ul> <li> <code>fastly.toml</code> where we set up the detail for the service, telling Fastly to use your remix of the Glitch website as the service origin (or <code>backend</code>)</li> <li> <code>src/index.js</code> where our Compute logic happens</li> </ul> <blockquote> <p>💡 We're using JavaScript, but you can code for Compute <a href="https://www.fastly.com/documentation/guides/compute/" target="_blank" rel="noopener noreferrer">in other languages</a>.</p> </blockquote> <p>Take a stroll through the <code>index.js</code> code:</p> <ul> <li>It uses a function to handle requests that come in from users</li> <li>The function can make changes to the request from the user, and the response from our Glitch origin website, before sending it back to the user</li> <li>We add geolocation information from the edge to the response, as a cookie the Glitch site will write into the page when the user's browser loads it</li> <li>We change the website stylesheet request path from <code>style.css</code> to <code>edge.css</code> (that's why the <code>edgecompute.app</code> version looks different)</li> </ul> <h3> <a name="what-happens-when-you-build-and-run" href="#what-happens-when-you-build-and-run"> </a> 🚧 What happens when you build and run </h3> <p>Although we're coding our app in JavaScript, what happens with edge computing is quite different from writing JS for environments like the browser or web server. When we develop Compute apps, Fastly is going to <em>compile</em> our source code into <a href="https://webassembly.org/" target="_blank" rel="noopener noreferrer">WebAssembly (Wasm)</a>.</p> <p>When we write a language like JavaScript, we have to do it differently for client and server side development, don't we? JS code works differently in the user's browser than it does on a web server, because they are different <em>runtime</em> environments. Apps can access different resources in the computing environment they run in, and this changes how you write your code. Well the edge is different again!</p> <p>When you deploy an app to the Fastly edge, it runs in the <a href="https://docs.wasmtime.dev/" target="_blank" rel="noopener noreferrer">Wasmtime</a> environment. This lets your apps run safely on Fastly's edge network in the cloud. Like client side vs server side JS, it also means that there are some differences in how you code your apps. The <a href="https://www.fastly.com/documentation/guides/compute/javascript/" target="_blank" rel="noopener noreferrer">JavaScript project structure for Compute</a> is generally similar to developing for Node.js.</p> <h2> <a name="set-up-your-fastly-account" href="#set-up-your-fastly-account"> </a> Set up your Fastly account </h2> <p><strong>If you haven't already, <a href="https://fastly.com/signup" target="_blank" rel="noopener noreferrer">sign up for a free Fastly developer account</a>.</strong></p> <p>In your account, grab an API token so that you can deploy from Glitch:</p> <ul> <li>Choose <strong>Account</strong> &gt; <strong>Personal Profile</strong> &gt; <strong>API Tokens</strong> &gt; <strong>Create Token</strong> </li> <li>Enter a <em>Name</em> of your choice and choose the following settings: <ul> <li> <em>Type</em>: Automation</li> <li> <em>Role</em>: Engineer</li> <li> <em>Scope</em>: Global (deselect the Read-only access box)</li> <li> <em>Access</em>: All services</li> <li> <em>Expiration</em>: Never expire</li> </ul> </li> </ul> <p>📋 Create your token and keep a copy of it on your computer.</p> <blockquote> <p>🚨 If you haven't created a Compute service in your Fastly account yet, you'll need to create one in the control panel before you can deploy from Glitch. Go to <strong>Home</strong> and choose <strong>Create service</strong> &gt; <strong>Compute</strong>. You can leave the service empty and pop back into Glitch, this just unlocks your ability to create Fastly services from the CLI in Glitch.</p> </blockquote> <p>Back in Glitch, paste your token into the project <code>.env</code> file as the value for <code>FASTLY_API_TOKEN</code>.</p> <h2> <a name="deploy-your-app-to-the-edge" href="#deploy-your-app-to-the-edge"> </a> Deploy your app to the edge </h2> <p>With your Fastly API key in your Glitch project, you're ready to deploy to Compute. Open your project <strong>Terminal</strong> and enter the command: <code>npm run publish</code></p> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6if4taipym996s0fcbat.jpg" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6if4taipym996s0fcbat.jpg" alt="CLI output" loading="lazy" width="800" height="234"></a></p> <blockquote> <p>⚠️ If you get an error indicating that you can't deploy your Compute service, try the note in the last step ^^ to unblock your account.</p> </blockquote> <p>Your Glitch app is preloaded with the Fastly CLI and some commands you can see in your <code>package.json</code> file. When you run the publish command, Fastly does a few things:</p> <ul> <li>Builds the code in your <code>edge</code> folder into WebAssembly</li> <li>Runs any relevant scripts in <code>edge/package.json</code> </li> <li>Creates a new service in your Fastly account</li> <li>Sets your Glitch website as the origin (or <code>backend</code>) for the service</li> <li>Uploads your Wasm package to the service</li> <li>Activates and deploys your new service across the Fastly network</li> </ul> <blockquote> <p>💡 The process might take a couple of minutes to complete, and a minute or so longer to actually load for the first time when you visit your site, so don't worry if it doesn't work straight away.</p> </blockquote> <p>When your service successfully activates, your <strong>Terminal</strong> output will display the address, which will have the same subdomain as your Glitch site, but with <code>edgecompute.app</code> instead of <code>glitch.me</code>.</p> <p>Go ahead and open it in your browser. You should find your own location and Fastly <a href="https://www.fastly.com/documentation/guides/concepts/pop/" target="_blank" rel="noopener noreferrer">POP (Point of Presence)</a> indicated in the page.</p> <p>That's it! You've built and deployed a serverless edge computing app that changes the UX for your website. 🌍🚀</p> <h3> <a name="make-a-bonus-edit" href="#make-a-bonus-edit"> </a> 🎁 Make a bonus edit </h3> <p>Follow Step 4 in the Glitch project <code>README</code> to show this bonus page during one hour at your website user's location.</p> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq8pl694psvcd82dyqjh7.jpg" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq8pl694psvcd82dyqjh7.jpg" alt="Bonus page" loading="lazy" width="800" height="903"></a></p> <p>🏆 <strong><a href="https://dev.to/fastly/get-edge-certified-with-new-fastly-credentials-409m">Make sure you claim your Edge Computing 101 badge</a></strong></p> <h2> <a name="what-else-can-you-do-at-the-edge" href="#what-else-can-you-do-at-the-edge"> </a> What else can you do at the edge? </h2> <p>The project we've worked through here is pretty basic, but you can do a lot more in your edge apps. Check out the tutorial in the Fastly docs for an app that carries out a few additional enhancements on a Glitch site:</p> <ul> <li><strong><a href="https://www.fastly.com/documentation/solutions/tutorials/enhance-ux/" target="_blank" rel="noopener noreferrer">Enhance your site UX with Compute</a></strong></li> </ul> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffqeokm1tlkosswuxnz3s.png" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffqeokm1tlkosswuxnz3s.png" alt="Origin and edge versions of the site" loading="lazy" width="800" height="404"></a></p> <p>The <a href="https://glitch.com/~fastly-compute-starter" target="_blank" rel="noopener noreferrer">~fastly-compute-starter</a> project handles website errors at the edge, password protects some pages, and builds JSON data into HTML.</p> <ul> <li>The Fastly docs have a ton of <a href="https://www.fastly.com/documentation/solutions/examples/" target="_blank" rel="noopener noreferrer">code examples</a> to try in the browser for inspiration</li> <li>Check out the <a href="https://www.fastly.com/documentation/solutions/use-cases/" target="_blank" rel="noopener noreferrer">types of Compute functionality you can add to your websites</a> </li> <li>You can even <a href="https://www.fastly.com/blog/no-origin-static-websites-at-the-edge/" target="_blank" rel="noopener noreferrer">serve entire generated static sites from the edge</a> without hosting them anywhere else</li> </ul> <p>🛟 <strong>For support, <a href="https://community.fastly.com" target="_blank" rel="noopener noreferrer">post in the Fastly community forum</a>.</strong></p> <p><strong><em>Share what you're building in the comments!</em></strong></p> </div> <div class="js-billboard-container body-billboard-container" data-async-url="/fastly/build-your-own-edge-computing-app-3cp2/bb-2/post_body_bottom"></div> </div> <section id="comments" data-follow-button-container="true" data-updated-at="2025-03-07 05:13:54 UTC" class="text-padding mb-4 border-t-1 border-0 border-solid border-base-10"> <header class="relative flex justify-between items-center mb-6"> <div class="flex items-center"> <h2 class="crayons-subtitle-1"> Top comments <span class="js-comments-count" data-comments-count="2">(2)</span> </h2> </div> <div id="comment-subscription" class="print-hidden"> <div class="crayons-btn-group"> <span class="crayons-btn crayons-btn--outlined">Subscribe</span> </div> </div> </header> <div id="billboard_delay_trigger"></div> <div id="comments-container" data-testid="comments-container" data-commentable-id="1994941" data-commentable-type="Article" data-has-recent-comment-activity="false"> <div id="response-templates-data" class="hidden"></div> <form class="comment-form print-hidden" id="new_comment" action="/comments" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="&#x2713;" autocomplete="off" /> <input type="hidden" name="authenticity_token" value="NOTHING" id="new_comment_authenticity_token"> <input value="1994941" autocomplete="off" type="hidden" name="comment[commentable_id]" id="comment_commentable_id" /> <input value="Article" autocomplete="off" type="hidden" name="comment[commentable_type]" id="comment_commentable_type" /> <span class="crayons-avatar m:crayons-avatar--l mr-2 shrink-0"> <img src="https://media2.dev.to/dynamic/image/width=256,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png" width="32" height="32" alt="pic" class="crayons-avatar__image overflow-hidden" id="comment-primary-user-profile--avatar" loading="lazy" /> </span> <div class="comment-form__inner"> <div class="comment-form__field" data-tracking-name="comment_form_textfield"> <textarea placeholder="Add to the discussion" onfocus="handleFocus(event)" onkeyup="handleKeyUp(event)" onkeydown="handleKeyDown(event)" oninput="handleChange(event)" id="text-area" required="required" class="crayons-textfield comment-textarea crayons-textfield--ghost" aria-label="Add a comment to the discussion" name="comment[body_markdown]"> </textarea> </div> <div class="response-templates-container crayons-card crayons-card--secondary p-4 mb-4 comment-form__templates fs-base hidden"> <header class="mb-3"> <button type="button" class="crayons-btn personal-template-button active" data-target-type="personal" data-form-id="new_comment">Personal</button> <button type="button" class="crayons-btn moderator-template-button hidden" data-target-type="moderator" data-form-id="new_comment">Trusted User</button> </header> <div class="personal-responses-container"> </div> <div class="moderator-responses-container hidden"> </div> <a target="_blank" rel="noopener nofollow" href="/settings/response-templates"> Create template </a> <p>Templates let you quickly answer FAQs or store snippets for re-use.</p> </div> <div class="comment-form__preview text-styles text-styles--secondary" id="preview-div"></div> <div class="comment-form__buttons mb-4"> <button type="submit" class="crayons-btn mr-2 js-btn-enable" onclick="validateField(event)" data-tracking-name="comment_submit_button" disabled>Submit</button> <button type="button" class="preview-toggle crayons-btn crayons-btn--secondary comment-action-preview js-btn-enable mr-2" data-tracking-name="comment_preview_button" disabled>Preview</button> <a href="/404.html" class="dismiss-edit-comment crayons-btn crayons-btn--ghost js-btn-dismiss hidden">Dismiss</a> </div> </div> <div class="code-of-conduct" id="toggle-code-of-conduct-checkbox"></div> </form> <div class="comments" id="comment-trees-container"> <details class="comment-wrapper js-comment-wrapper comment-wrapper--deep-0 root " open> <summary aria-label="Toggle this comment (and replies)" data-tracking-name="expand_comment_toggle"> <span class="m:mx-1 inline-block align-middle"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" aria-labelledby="azh89sh3dnxkmsu4w8t1feopvm0xn3v" class="crayons-icon expanded"><title id="azh89sh3dnxkmsu4w8t1feopvm0xn3v">Collapse</title> <path d="M12 10.677L8 6.935 9 6l3 2.807L15 6l1 .935-4 3.742zm0 4.517L9 18l-1-.935 4-3.742 4 3.742-1 .934-3-2.805z"></path> </svg> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" aria-labelledby="afwfseotnr0ib7v23q8eoe85iqojq23f" class="crayons-icon collapsed"><title id="afwfseotnr0ib7v23q8eoe85iqojq23f">Expand</title> <path d="M12 18l-4-3.771 1-.943 3 2.829 3-2.829 1 .943L12 18zm0-10.115l-3 2.829-1-.943L12 6l4 3.771-1 .942-3-2.828z"></path> </svg> </span> <span class="js-collapse-comment-content inline-block align-middle"></span> </summary> <div id="comment-node-1234051" class=" comment single-comment-node root comment--deep-0 " data-comment-id="1234051" data-path="/fastly/build-your-own-edge-computing-app-3cp2/comments/2i5dd" data-comment-author-id="1748265" data-content-user-id="1748265"> <a name="comment-2i5dd" style="position: absolute; top: -8px;">&nbsp;</a> <div class="comment__inner"> <a href="https://dev.to/jance_jacobs" class="shrink-0 crayons-avatar m:crayons-avatar--l mt-4 m:mt-3"> <img class="crayons-avatar__image" width="32" height="32" src="https://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1748265%2F12476033-c9c0-41a9-81d2-d3a33c0ec5b8.png" alt="jance_jacobs profile image" loading="lazy" /> </a> <div class="inner-comment comment__details"> <div class="comment__content crayons-card"> <div class="comment__header"> <a href="https://dev.to/jance_jacobs" class="crayons-link crayons-link--secondary flex items-center fw-medium m:hidden"> <span class="js-comment-username">Jance Jacobs</span> </a> <div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:block"> <button id="comment-profile-preview-trigger-1234051" aria-controls="comment-profile-preview-content-1234051" class="profile-preview-card__trigger p-1 -my-1 -ml-1 crayons-btn crayons-btn--ghost" aria-label="Jance Jacobs profile details"> Jance Jacobs </button> <div id="comment-profile-preview-content-1234051" class="profile-preview-card__content p-4 pt-0 branded-7 crayons-dropdown" style="--card-color: #000000; border-top-color: var(--card-color);" data-testid="profile-preview-card" data-repositioning-dropdown="true"> <div class="gap-4 grid"> <div class="-mt-4"> <a href="/jance_jacobs" class="flex"> <span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"> <img src="https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1748265%2F12476033-c9c0-41a9-81d2-d3a33c0ec5b8.png" class="crayons-avatar__image" alt="" loading="lazy" /> </span> <span class="crayons-link crayons-subtitle-2 mt-5"> Jance Jacobs </span> </a> </div> <div class="print-hidden"> <button name="button" type="button" data-info="{&quot;className&quot;:&quot;User&quot;,&quot;style&quot;:&quot;&quot;,&quot;id&quot;:1748265,&quot;name&quot;:&quot;Jance Jacobs&quot;}" class="crayons-btn follow-action-button whitespace-nowrap w-100 follow-user" aria-label="Follow user: Jance Jacobs" aria-pressed="false">Follow</button> </div> <div class="user-metadata-details"> <ul class="user-metadata-details-inner"> <li> <div class="key"> Joined </div> <div class="value"> <time datetime="2024-07-08T15:05:05Z" class="date">Jul 8, 2024</time> </div> </li> </ul> </div> </div> </div> </div> <span class="color-base-30 px-2 m:pl-0" role="presentation">&bull;</span> <a href="https://dev.to/fastly/build-your-own-edge-computing-app-3cp2#comment-2i5dd" class="comment-date crayons-link crayons-link--secondary fs-s"> <time datetime="2024-09-16T12:34:48Z" class=date-short-year> Sep 16 &#39;24 </time> </a> <div class="comment__dropdown" data-tracking-name="comment_dropdown"> <button id="comment-dropdown-trigger-1234051" aria-controls="comment-dropdown-1234051" aria-expanded="false" class="dropbtn comment__dropdown-trigger crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon " aria-label="Toggle dropdown menu" aria-haspopup="true"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" aria-labelledby="a57nc8oco3ghtgjm395zhlqfdy6n8bgw" class="crayons-icon pointer-events-none"><title id="a57nc8oco3ghtgjm395zhlqfdy6n8bgw">Dropdown menu</title> <path fill-rule="evenodd" clip-rule="evenodd" d="M8.25 12a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm5.25 0a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm3.75 1.5a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"></path> </svg> </button> <div id="comment-dropdown-1234051" class="crayons-dropdown right-1 s:right-0 s:left-auto fs-base dropdown"> <ul class="m-0"> <li><a href="https://dev.to/fastly/build-your-own-edge-computing-app-3cp2#comment-2i5dd" class="crayons-link crayons-link--block permalink-copybtn" aria-label="Copy link to Jance Jacobs&#39;s comment" data-no-instant>Copy link</a></li> <li class="comment-actions hidden" data-user-id="1748265" data-action="settings-button" data-path="https://dev.to/jance_jacobs/comment/2i5dd/settings" aria-label="Go to Jance Jacobs&#39;s comment settings"></li> <li class="comment-actions hidden" data-action="hide-button" data-commentable-user-id="154099" data-user-id="1748265"> <button class="flex justify-between crayons-link crayons-link--block w-100 bg-transparent border-0 hide-comment" data-hide-type="hide" data-comment-id="1234051" data-comment-url="https://dev.to/jance_jacobs/comment/2i5dd" aria-label="Hide Jance Jacobs&#39;s comment"> Hide </button> </li> <li class="mod-actions hidden mod-actions-comment-button" data-path="https://dev.to/jance_jacobs/comment/2i5dd/mod" aria-label="Moderate Jance Jacobs&#39;s comment"></li> <li class="report-abuse-link-wrapper" data-path="/report-abuse?url=https://dev.to/jance_jacobs/comment/2i5dd" aria-label="Report Jance Jacobs&#39;s comment as abusive or violating our code of conduct and/or terms and conditions"></li> <li class="current-user-actions"></li> </ul> </div> </div> </div> <div class=" comment__body text-styles text-styles--secondary body "> <p>This is a fascinating introduction to edge computing! I'm curious though, how would this approach compare to using traditional CDNs for improving site performance?</p> </div> </div> <script> </script> <footer class="comment__footer print-hidden"> <button class="crayons-tooltip__activator crayons-btn crayons-btn--ghost crayons-btn--icon-left crayons-btn--s mr-1 reaction-like inline-flex reaction-button" id="button-for-comment-1234051" data-comment-id="1234051" aria-label="like" data-tracking-name="comment_heart_button"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" role="img" aria-labelledby="a4fh3r2eze5qn0f2ytfa652vv9z9sxgb" class="crayons-icon reaction-icon not-reacted"><title id="a4fh3r2eze5qn0f2ytfa652vv9z9sxgb">Like comment: </title><path d="M18.884 12.595l.01.011L12 19.5l-6.894-6.894.01-.01A4.875 4.875 0 0112 5.73a4.875 4.875 0 016.884 6.865zM6.431 7.037a3.375 3.375 0 000 4.773L12 17.38l5.569-5.569a3.375 3.375 0 10-4.773-4.773L9.613 10.22l-1.06-1.062 2.371-2.372a3.375 3.375 0 00-4.492.25v.001z"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" aria-labelledby="aaeoxo5vew9ix1r2ox1q0pex2j7fr0d0" class="crayons-icon crayons-icon reaction-icon--like reaction-icon reacted"><title id="aaeoxo5vew9ix1r2ox1q0pex2j7fr0d0">Like comment: </title> <path d="M5.116 12.595a4.875 4.875 0 015.56-7.68h-.002L7.493 8.098l1.06 1.061 3.181-3.182a4.875 4.875 0 016.895 6.894L12 19.5l-6.894-6.894.01-.01z"></path> </svg> <span class="reactions-count">2</span><span class="reactions-label hidden m:inline-block">&nbsp;likes</span> <span data-testid="tooltip" class="crayons-tooltip__content"> Like </span> </button> <a class="actions crayons-btn crayons-btn--ghost crayons-btn--s crayons-btn--icon-left toggle-reply-form mr-1 inline-flex" href="#/fastly/build-your-own-edge-computing-app-3cp2/comments/new/2i5dd" data-comment-id="1234051" data-path="/fastly/build-your-own-edge-computing-app-3cp2/comments/2i5dd" data-tracking-name="comment_reply_button" data-testid="reply-button-1234051" rel="nofollow"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" role="img" aria-labelledby="a3ddagbv1d7fkiqtptdmewzcq1e62a9" class="crayons-icon reaction-icon not-reacted"><title id="a3ddagbv1d7fkiqtptdmewzcq1e62a9">Comment button</title><path d="M10.5 5h3a6 6 0 110 12v2.625c-3.75-1.5-9-3.75-9-8.625a6 6 0 016-6zM12 15.5h1.5a4.501 4.501 0 001.722-8.657A4.5 4.5 0 0013.5 6.5h-3A4.5 4.5 0 006 11c0 2.707 1.846 4.475 6 6.36V15.5z"></path></svg> <span class="hidden m:inline-block">Reply</span> </a> </footer> </div> </div> <details class="comment-wrapper js-comment-wrapper comment-wrapper--deep-1 child " open> <summary aria-label="Toggle this comment (and replies)" data-tracking-name="expand_comment_toggle"> <span class="mx-0 inline-block align-middle"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" aria-labelledby="a5c68eabinyl4zyh2f796wuc08tymtkz" class="crayons-icon expanded"><title id="a5c68eabinyl4zyh2f796wuc08tymtkz">Collapse</title> <path d="M12 10.677L8 6.935 9 6l3 2.807L15 6l1 .935-4 3.742zm0 4.517L9 18l-1-.935 4-3.742 4 3.742-1 .934-3-2.805z"></path> </svg> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" aria-labelledby="a7hc4692gsmn28y9u0e3oewciwgal40r" class="crayons-icon collapsed"><title id="a7hc4692gsmn28y9u0e3oewciwgal40r">Expand</title> <path d="M12 18l-4-3.771 1-.943 3 2.829 3-2.829 1 .943L12 18zm0-10.115l-3 2.829-1-.943L12 6l4 3.771-1 .942-3-2.828z"></path> </svg> </span> <span class="js-collapse-comment-content inline-block align-middle"></span> </summary> <div id="comment-node-1237081" class=" comment single-comment-node child comment--deep-1 " data-comment-id="1237081" data-path="/fastly/build-your-own-edge-computing-app-3cp2/comments/2ia01" data-comment-author-id="154099" data-content-user-id="154099"> <a name="comment-2ia01" style="position: absolute; top: -8px;">&nbsp;</a> <div class="comment__inner"> <a href="https://dev.to/suesmith" class="shrink-0 crayons-avatar mt-4"> <img class="crayons-avatar__image" width="32" height="32" src="https://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F154099%2F9d185df0-7f11-45be-a0d9-a24997721513.jpg" alt="suesmith profile image" loading="lazy" /> </a> <div class="inner-comment comment__details"> <div class="comment__content crayons-card"> <div class="comment__header"> <a href="https://dev.to/suesmith" class="crayons-link crayons-link--secondary flex items-center fw-medium m:hidden"> <span class="js-comment-username">Sue Smith</span> <span class="crayons-hover-tooltip inline-block spec-op-author -mr-2" data-tooltip="Author"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" class="crayons-icon"> <path d="M12 8.25a6 6 0 110 12 6 6 0 010-12zm0 2.625l-.992 2.01-2.218.322 1.605 1.564-.379 2.21L12 15.937l1.984 1.043-.379-2.209 1.605-1.564-2.218-.323L12 10.875zm.75-6.376l3.75.001v2.25l-1.022.854a7.45 7.45 0 00-2.728-.817V4.5zm-1.5 0v2.288a7.451 7.451 0 00-2.727.816L7.5 6.75V4.5h3.75z"></path> </svg> </span> </a> <div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:block"> <button id="comment-profile-preview-trigger-1237081" aria-controls="comment-profile-preview-content-1237081" class="profile-preview-card__trigger p-1 -my-1 -ml-1 crayons-btn crayons-btn--ghost" aria-label="Sue Smith profile details"> Sue Smith </button> <div id="comment-profile-preview-content-1237081" class="profile-preview-card__content p-4 pt-0 branded-7 crayons-dropdown" style="--card-color: #9f0aa4; border-top-color: var(--card-color);" data-testid="profile-preview-card" data-repositioning-dropdown="true"> <div class="gap-4 grid"> <div class="-mt-4"> <a href="/suesmith" class="flex"> <span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"> <img src="https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F154099%2F9d185df0-7f11-45be-a0d9-a24997721513.jpg" class="crayons-avatar__image" alt="" loading="lazy" /> </span> <span class="crayons-link crayons-subtitle-2 mt-5"> Sue Smith </span> </a> </div> <div class="print-hidden"> <button name="button" type="button" data-info="{&quot;className&quot;:&quot;User&quot;,&quot;style&quot;:&quot;&quot;,&quot;id&quot;:154099,&quot;name&quot;:&quot;Sue Smith&quot;}" class="crayons-btn follow-action-button whitespace-nowrap w-100 follow-user" aria-label="Follow user: Sue Smith" aria-pressed="false">Follow</button> </div> <div class="color-base-70"> Writes code to help folk learn to write code </div> <div class="user-metadata-details"> <ul class="user-metadata-details-inner"> <li> <div class="key"> Location </div> <div class="value"> Glasgow </div> </li> <li> <div class="key"> Pronouns </div> <div class="value"> she/her </div> </li> <li> <div class="key"> Joined </div> <div class="value"> <time datetime="2019-04-08T09:59:59Z" class="date">Apr 8, 2019</time> </div> </li> </ul> </div> </div> </div> <span class="crayons-hover-tooltip inline-block spec-op-author -ml-2" data-tooltip="Author"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" class="crayons-icon"> <path d="M12 8.25a6 6 0 110 12 6 6 0 010-12zm0 2.625l-.992 2.01-2.218.322 1.605 1.564-.379 2.21L12 15.937l1.984 1.043-.379-2.209 1.605-1.564-2.218-.323L12 10.875zm.75-6.376l3.75.001v2.25l-1.022.854a7.45 7.45 0 00-2.728-.817V4.5zm-1.5 0v2.288a7.451 7.451 0 00-2.727.816L7.5 6.75V4.5h3.75z"></path> </svg> </span> </div> <span class="color-base-30 px-2 m:pl-0" role="presentation">&bull;</span> <a href="https://dev.to/fastly/build-your-own-edge-computing-app-3cp2#comment-2ia01" class="comment-date crayons-link crayons-link--secondary fs-s"> <time datetime="2024-09-23T10:29:08Z" class=date-short-year> Sep 23 &#39;24 </time> </a> <div class="comment__dropdown" data-tracking-name="comment_dropdown"> <button id="comment-dropdown-trigger-1237081" aria-controls="comment-dropdown-1237081" aria-expanded="false" class="dropbtn comment__dropdown-trigger crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon " aria-label="Toggle dropdown menu" aria-haspopup="true"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" aria-labelledby="abfv2j0i8tcfhd9rxjvr0r3tw695iddk" class="crayons-icon pointer-events-none"><title id="abfv2j0i8tcfhd9rxjvr0r3tw695iddk">Dropdown menu</title> <path fill-rule="evenodd" clip-rule="evenodd" d="M8.25 12a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm5.25 0a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm3.75 1.5a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"></path> </svg> </button> <div id="comment-dropdown-1237081" class="crayons-dropdown right-1 s:right-0 s:left-auto fs-base dropdown"> <ul class="m-0"> <li><a href="https://dev.to/fastly/build-your-own-edge-computing-app-3cp2#comment-2ia01" class="crayons-link crayons-link--block permalink-copybtn" aria-label="Copy link to Sue Smith&#39;s comment" data-no-instant>Copy link</a></li> <li class="comment-actions hidden" data-user-id="154099" data-action="settings-button" data-path="https://dev.to/suesmith/comment/2ia01/settings" aria-label="Go to Sue Smith&#39;s comment settings"></li> <li class="comment-actions hidden" data-action="hide-button" data-commentable-user-id="154099" data-user-id="154099"> <button class="flex justify-between crayons-link crayons-link--block w-100 bg-transparent border-0 hide-comment" data-hide-type="hide" data-comment-id="1237081" data-comment-url="https://dev.to/suesmith/comment/2ia01" aria-label="Hide Sue Smith&#39;s comment"> Hide </button> </li> <li class="mod-actions hidden mod-actions-comment-button" data-path="https://dev.to/suesmith/comment/2ia01/mod" aria-label="Moderate Sue Smith&#39;s comment"></li> <li class="report-abuse-link-wrapper" data-path="/report-abuse?url=https://dev.to/suesmith/comment/2ia01" aria-label="Report Sue Smith&#39;s comment as abusive or violating our code of conduct and/or terms and conditions"></li> <li class="current-user-actions"></li> </ul> </div> </div> </div> <div class=" comment__body text-styles text-styles--secondary body "> <p>Thank you! So where a CDN is focused on delivering content quickly, edge computing is more optimised for building functionality, running different types of service, and integrating whatever you want to do at the edge into the development pipeline. In practice you can do a lot of the same things, for Fastly (where I work) Compute essentially gives you the ability to program whatever service you run on the edge network more easily by leveraging the languages, frameworks, tooling etc dev teams are already using. Hope that answers the question!</p> </div> </div> <script> </script> <footer class="comment__footer print-hidden"> <button class="crayons-tooltip__activator crayons-btn crayons-btn--ghost crayons-btn--icon-left crayons-btn--s mr-1 reaction-like inline-flex reaction-button" id="button-for-comment-1237081" data-comment-id="1237081" aria-label="like" data-tracking-name="comment_heart_button"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" role="img" aria-labelledby="aop1anqmt1xl7sxr82alifuabhpj663u" class="crayons-icon reaction-icon not-reacted"><title id="aop1anqmt1xl7sxr82alifuabhpj663u">Like comment: </title><path d="M18.884 12.595l.01.011L12 19.5l-6.894-6.894.01-.01A4.875 4.875 0 0112 5.73a4.875 4.875 0 016.884 6.865zM6.431 7.037a3.375 3.375 0 000 4.773L12 17.38l5.569-5.569a3.375 3.375 0 10-4.773-4.773L9.613 10.22l-1.06-1.062 2.371-2.372a3.375 3.375 0 00-4.492.25v.001z"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" aria-labelledby="acxhcxr2f0gr6zu4xmkdd4hzq0drkg9o" class="crayons-icon crayons-icon reaction-icon--like reaction-icon reacted"><title id="acxhcxr2f0gr6zu4xmkdd4hzq0drkg9o">Like comment: </title> <path d="M5.116 12.595a4.875 4.875 0 015.56-7.68h-.002L7.493 8.098l1.06 1.061 3.181-3.182a4.875 4.875 0 016.895 6.894L12 19.5l-6.894-6.894.01-.01z"></path> </svg> <span class="reactions-count">1</span><span class="reactions-label hidden m:inline-block">&nbsp;like</span> <span data-testid="tooltip" class="crayons-tooltip__content"> Like </span> </button> <a class="actions crayons-btn crayons-btn--ghost crayons-btn--s crayons-btn--icon-left toggle-reply-form mr-1 inline-flex" href="#/fastly/build-your-own-edge-computing-app-3cp2/comments/new/2ia01" data-comment-id="1237081" data-path="/fastly/build-your-own-edge-computing-app-3cp2/comments/2ia01" data-tracking-name="comment_reply_button" data-testid="reply-button-1237081" rel="nofollow"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" role="img" aria-labelledby="apu7su0vk1u90qtixyafubgnpfnu3hzv" class="crayons-icon reaction-icon not-reacted"><title id="apu7su0vk1u90qtixyafubgnpfnu3hzv">Comment button</title><path d="M10.5 5h3a6 6 0 110 12v2.625c-3.75-1.5-9-3.75-9-8.625a6 6 0 016-6zM12 15.5h1.5a4.501 4.501 0 001.722-8.657A4.5 4.5 0 0013.5 6.5h-3A4.5 4.5 0 006 11c0 2.707 1.846 4.475 6 6.36V15.5z"></path></svg> <span class="hidden m:inline-block">Reply</span> </a> </footer> </div> </div> </div> </details> </div> </details> </div> </div> <div class="align-center"> <nav class="fs-s align-center block" aria-label="Conduct controls"> <a href="/code-of-conduct" class="crayons-link crayons-link--secondary">Code of Conduct</a> <span class="opacity-25 px-2" role="presentation">&bull;</span> <a href="/report-abuse" class="crayons-link crayons-link--secondary">Report abuse</a> </nav> </div> </section> <div id="hide-comments-modal" class="hidden"> <form id="hide-comments-modal__form" class="hide-comments-modal__form" data-type="json" action="/comments/hide" accept-charset="UTF-8" data-remote="true" method="post"><input name="utf8" type="hidden" value="&#x2713;" autocomplete="off" /><input type="hidden" name="_method" value="patch" autocomplete="off" /><input type="hidden" name="authenticity_token" value="-rSy4kBmivy1LTyQwypUnCCuTG5H-S8labdg4J-2v1CgcXshTHcpFonyYq00k4dHjB5wSnzi-I-A4Yff5nTCvQ" autocomplete="off" /> <div class="hide-comments-modal__content"> <p class="pb-2"> Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's <a id="hide-comments-modal__comment-permalink" href="#">permalink</a>. </p> <label class="crayons-field crayons-field--checkbox my-2"> <input name="hide_children" type="hidden" value="0" autocomplete="off" /><input class="hide_children crayons-checkbox" type="checkbox" value="1" name="hide_children" id="hide_children" /> <p class="crayons-field__label">Hide child comments as well</p> </label> <p class="pb-4 pt-2"> <button type="submit" class="crayons-btn"> Confirm </button> </p> </div> </form> <p class="fs-s color-base-60">For further actions, you may consider blocking this person and/or <a id="hide-comments-modal__report-link" href="/report-abuse">reporting abuse</a></p> </div> </article> <div class="pb-4 crayons-layout__comments-billboard"> <div class="js-billboard-container pb-4 crayons-layout__comments-billboard" data-async-url="/fastly/build-your-own-edge-computing-app-3cp2/bb-2/post_comments"></div> </div> <section class="crayons-card crayons-card--secondary text-padding mb-4 print-hidden" id="bottom-content-read-next"> <h2 class="crayons-subtitle-1">Read next</h2> <a href="/alexandrughinea/the-hyper-specialization-dilemma-in-modern-web-development-rant-48p5" data-preload-image="" class="crayons-link mt-6 block"> <div class="flex items-center"> <span class="crayons-avatar crayons-avatar--xl m:crayons-avatar--2xl mr-4 shrink-0"> <img loading="lazy" alt="alexandrughinea profile image" class="crayons-avatar__image" width="100" height="100" src="https://media2.dev.to/dynamic/image/width=100,height=100,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F149315%2F344dc231-26c5-4223-8101-3b58d07eef38.png" /> </span> <div> <h3 class="fs-xl mb-0 lh-tight">The Hyper-Specialization Dilemma in Modern Web Development - Rant</h3> <p class="opacity-75 pt-1"> Alex R. - <time datetime="2024-12-16T16:41:47Z">Dec 16 &#39;24</time> </p> </div> </div> </a> <a href="/sunwukong/what-is-cloud-computing-and-why-it-matters-2fm8" data-preload-image="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhno2y6yp3mvv8kkk8odo.jpg" class="crayons-link mt-6 block"> <div class="flex items-center"> <span class="crayons-avatar crayons-avatar--xl m:crayons-avatar--2xl mr-4 shrink-0"> <img loading="lazy" alt="sunwukong profile image" class="crayons-avatar__image" width="100" height="100" src="https://media2.dev.to/dynamic/image/width=100,height=100,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1223166%2F129e7b75-c06a-4b13-8d23-aa3fd7c4985d.jpg" /> </span> <div> <h3 class="fs-xl mb-0 lh-tight">What is Cloud Computing and Why It Matters?</h3> <p class="opacity-75 pt-1"> Anthony - <time datetime="2024-12-03T16:03:11Z">Dec 3 &#39;24</time> </p> </div> </div> </a> <a href="/zororaka/when-to-use-vps-vercel-and-cloudflare-worker-a-detailed-comparison-3nm0" data-preload-image="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkisd7sz3bftbzq9nntr6.png" class="crayons-link mt-6 block"> <div class="flex items-center"> <span class="crayons-avatar crayons-avatar--xl m:crayons-avatar--2xl mr-4 shrink-0"> <img loading="lazy" alt="zororaka profile image" class="crayons-avatar__image" width="100" height="100" src="https://media2.dev.to/dynamic/image/width=100,height=100,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2561871%2F54c1d645-7bb8-4373-bb3f-b96a86f03938.jpg" /> </span> <div> <h3 class="fs-xl mb-0 lh-tight">🚀 When to Use VPS, Vercel, and Cloudflare Worker: A Detailed Comparison</h3> <p class="opacity-75 pt-1"> Raka Widhi Antoro - <time datetime="2024-12-15T15:41:48Z">Dec 15 &#39;24</time> </p> </div> </div> </a> <a href="/madgan95/amazon-web-services-2d7m" data-preload-image="https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fta4q9ytg38ymcu04wqc1.png" class="crayons-link mt-6 block"> <div class="flex items-center"> <span class="crayons-avatar crayons-avatar--xl m:crayons-avatar--2xl mr-4 shrink-0"> <img loading="lazy" alt="madgan95 profile image" class="crayons-avatar__image" width="100" height="100" src="https://media2.dev.to/dynamic/image/width=100,height=100,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1624058%2Ff865c284-6ea7-49e1-b284-edc156c245af.png" /> </span> <div> <h3 class="fs-xl mb-0 lh-tight">Amazon Web Services</h3> <p class="opacity-75 pt-1"> Madhav Ganesan - <time datetime="2025-01-01T06:01:42Z">Jan 1</time> </p> </div> </div> </a> </section> </div> </main> <aside class="crayons-layout__sidebar-right" aria-label="Author details"> <div class="crayons-article-sticky grid gap-4 pb-4 break-word" id="article-show-primary-sticky-nav"> <div class="crayons-card crayons-card--secondary branded-7 p-4 pt-0 gap-4 grid" style="border-top-color: #e02100;"> <div class="-mt-4"> <a href="/fastly" class="flex"> <span class="crayons-logo crayons-logo--xl mr-2 shrink-0"> <img src="https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F2298%2F27608760-4be1-4e12-b054-b8a2748d978d.png" class="crayons-logo__image" alt="" loading="lazy" /> </span> <span class="crayons-link crayons-subtitle-2 mt-5"> Fastly </span> </a> </div> <div class="print-hidden"> <button name="button" type="button" data-info="{&quot;className&quot;:&quot;Organization&quot;,&quot;style&quot;:&quot;&quot;,&quot;id&quot;:2298,&quot;name&quot;:&quot;Fastly&quot;}" class="crayons-btn follow-action-button whitespace-nowrap w-100 " aria-label="Follow organization: Fastly" aria-pressed="false">Follow</button> </div> </div> <div class="crayons-card crayons-card--secondary"> <header class="crayons-card__header"> <h3 class="crayons-subtitle-2"> More from <a href="/fastly">Fastly</a> </h3> </header> <div> <a class="crayons-link crayons-link--contentful" href="/fastly/announcing-the-pubsub-compute-app-35ki"> Announcing the Pub/Sub Compute app <div class="crayons-link__secondary -ml-1"> <span class="mr-1"><span class="opacity-50">#</span>pubsub</span> <span class="mr-1"><span class="opacity-50">#</span>serverless</span> <span class="mr-1"><span class="opacity-50">#</span>rust</span> <span class="mr-1"><span class="opacity-50">#</span>opensource</span> </div> </a> <a class="crayons-link crayons-link--contentful" href="/fastly/go-beyond-the-basics-connecting-compute-to-object-storage-with-the-official-s3-clients-4l9p"> Go Beyond the Basics: Connecting Compute to Object Storage with the Official S3 Clients <div class="crayons-link__secondary -ml-1"> <span class="mr-1"><span class="opacity-50">#</span>fastly</span> <span class="mr-1"><span class="opacity-50">#</span>serverless</span> <span class="mr-1"><span class="opacity-50">#</span>webassembly</span> <span class="mr-1"><span class="opacity-50">#</span>s3</span> </div> </a> <a class="crayons-link crayons-link--contentful" href="/fastly/get-edge-certified-with-new-fastly-credentials-409m"> Get edge certified with new Fastly credentials <div class="crayons-link__secondary -ml-1"> <span class="mr-1"><span class="opacity-50">#</span>cloud</span> <span class="mr-1"><span class="opacity-50">#</span>webdev</span> <span class="mr-1"><span class="opacity-50">#</span>certification</span> <span class="mr-1"><span class="opacity-50">#</span>career</span> </div> </a> </div> </div> </div> <div class="crayons-article-sticky grid gap-4 break-word js-billboard-container" data-async-url="/fastly/build-your-own-edge-computing-app-3cp2/bb-2/post_sidebar"></div> </aside> </div> <script> if (document.getElementsByClassName('fluidvids').length === 0) { window.Fluidvids=function(a,b){"use strict";var c,d,e=b.head||b.head,f=".fluidvids-elem{position:absolute;top:0px;left:0px;width:100%;height:100%;border:none;}.fluidvids{width:100%;position:relative;}",g=function(a){return c=new RegExp("^(https?:)?//(?:"+d.join("|")+").*$","i"),c.test(a)},h=function(a){var c=b.createElement("div"),d=a.parentNode,e=100*(parseInt(a.height?a.height:a.offsetHeight,10)/parseInt(a.width?a.width:a.offsetWidth,10));d.insertBefore(c,a),a.className+=" fluidvids-elem",c.className+=" fluidvids",c.style.paddingTop=e+"%",c.appendChild(a)},i=function(){var a=b.createElement("div");a.innerHTML="<p>x</p><style>"+f+"</style>",e.appendChild(a.childNodes[1])},j=function(a){var c=a||{},e=c.selector||"iframe";d=c.players||["www.youtube.com","player.vimeo.com","clips.twitch.tv"];for(var f=b.querySelectorAll(e),j=0;j<f.length;j++){var k=f[j];g(k.src)&&h(k)}i()};return{init:j}}(window,document); Fluidvids.init({ selector: ['iframe', 'object'], // runs querySelectorAll() players: ['www.youtube.com', 'player.vimeo.com', 'clips.twitch.tv'] // players to support }); } </script> <div class="mod-actions-menu print-hidden"></div> <div data-testid="unpublish-post-modal-container" class="unpublish-post-modal-container hidden"></div> <div class="fullscreen-code js-fullscreen-code"></div> <script src="https://assets.dev.to/assets/followButtons-f2455d1f50a862b83fa006b1953e3a1644598781243cae25d3e75b13c04184fd.js" defer="defer"></script> <script src="https://assets.dev.to/assets/billboard-f7c8c27ea139e85e7eb2a1adec43d4757a9edf002f434e8ba0eca486c39a6e60.js" defer="defer"></script> <script src="https://assets.dev.to/assets/localizeArticleDates-70147c5c6bfe350b42e020ebb2a3dd37419d83978982b5a67b6389119bf162ac.js" defer="defer"></script> <script src="https://assets.dev.to/assets/articleReactions-79a44d82fb34a91c3987c24cfd3bcf2b0d38a02730b69ae6da297387d185f015.js" defer="defer"></script> <script> function activateRunkitTags() { if (!areAnyRunkitTagsPresent()) return var checkRunkit = setInterval(function() { try { dynamicallyLoadRunkitLibrary() if (typeof(RunKit) === 'undefined') { return } replaceTagContentsWithRunkitWidget() clearInterval(checkRunkit); } catch(e) { console.error(e); clearInterval(checkRunkit); } }, 200); } function isRunkitTagAlreadyActive(runkitTag) { return runkitTag.querySelector("iframe") !== null; }; function areAnyRunkitTagsPresent() { var presentRunkitTags = document.getElementsByClassName("runkit-element"); return presentRunkitTags.length > 0 } function replaceTagContentsWithRunkitWidget() { var targets = document.getElementsByClassName("runkit-element"); for (var i = 0; i < targets.length; i++) { if (isRunkitTagAlreadyActive(targets[i])) { continue; } var wrapperContent = targets[i].textContent; if (/^(<iframe src)/.test(wrapperContent) === false) { if (targets[i].children.length > 0) { var preamble = targets[i].children[0].textContent; var content = targets[i].children[1].textContent; targets[i].innerHTML = ""; var notebook = RunKit.createNotebook({ element: targets[i], source: content, preamble: preamble }); } } } }; function dynamicallyLoadRunkitLibrary() { if (typeof(dynamicallyLoadScript) === "undefined") return dynamicallyLoadScript("//embed.runkit.com") } activateRunkitTags(); </script> <div class="js-billboard-container pb-4 crayons-layout__comments-billboard" data-async-url="/fastly/build-your-own-edge-computing-app-3cp2/bb-2/post_fixed_bottom"></div> <div id="runtime-banner-container"></div> </div> </div> <footer id="footer" class="crayons-footer print-hidden"> <div id="footer-container" class="crayons-footer__container"> <p class="fs-s crayons-footer__description"> <a class="c-link c-link--branded fw-medium" aria-label="DEV Community Home" href="/">DEV Community</a> — A constructive and inclusive social network for software developers. With you every step of your journey. </p> <ul class="footer__nav-links flex gap-2 justify-center flex-wrap fs-s p-0" style="" /> <li class="footer__nav-link flex items-center"> <a href="/"> Home </a> <span class="dot ml-2"></span> </li> <li class="footer__nav-link flex items-center"> <a href="/tags"> Tags </a> <span class="dot ml-2"></span> </li> <li class="footer__nav-link flex items-center"> <a href="/about"> About </a> <span class="dot ml-2"></span> </li> <li class="footer__nav-link flex items-center"> <a href="/contact"> Contact </a> <span class="dot ml-2"></span> </li> </ul> <ul class="footer__nav-links flex gap-2 justify-center flex-wrap fs-s p-0" style="" /> <li class="footer__nav-link flex items-center"> <a href="/code-of-conduct"> Code of Conduct </a> <span class="dot ml-2"></span> </li> <li class="footer__nav-link flex items-center"> <a href="/privacy"> Privacy Policy </a> <span class="dot ml-2"></span> </li> <li class="footer__nav-link flex items-center"> <a href="/terms"> Terms of use </a> <span class="dot ml-2"></span> </li> </ul> <div class="fs-s"> <p>Built on <a class="c-link c-link--branded" target="_blank" rel="noopener" href="https://www.forem.com">Forem</a> — the <a target="_blank" rel="noopener" class="c-link c-link--branded" href="https://dev.to/t/opensource">open source</a> software that powers <a target="_blank" rel="noopener" class="c-link c-link--branded" href="https://dev.to">DEV</a> and other inclusive communities.</p> <p>Made with love and <a target="_blank" rel="noopener" class="c-link c-link--branded" href="https://dev.to/t/rails">Ruby on Rails</a>. DEV Community <span title="copyright">&copy;</span> 2016 - 2025.</p> </div> </div> </footer> <div id="snack-zone"></div> <div id="global-signup-modal" class="authentication-modal hidden"> <div class="authentication-modal__container"> <figure class="authentication-modal__image-container"> <img class="authentication-modal__image" src="https://media2.dev.to/dynamic/image/width=190,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png" alt="DEV Community" loading="lazy" /> </figure> <div class="authentication-modal__content"> <p class="authentication-modal__description"> We&#39;re a place where coders share, stay up-to-date and grow their careers. </p> </div> <div class="authentication-modal__actions"> <a href="/enter" class="crayons-btn" aria-label="Log in" data-no-instant> Log in </a> <a href="/enter?state=new-user" class="crayons-btn crayons-btn--ghost-brand js-global-signup-modal__create-account" aria-label="Create new account" data-no-instant> Create account </a> </div> </div> </div> <script src="https://assets.dev.to/assets/signupModalShortcuts-0b25469b985100a01e94cbd7fccaf7f0a4d776e129aac65c766aa32cb28ab29a.js" defer="defer"></script> <div id="cookie-consent"></div> <div id="i18n-translations" data-translations="{&quot;en&quot;:{&quot;core&quot;:{&quot;add_comment&quot;:&quot;Add comment&quot;,&quot;beta&quot;:&quot;beta&quot;,&quot;comment&quot;:&quot;Comment&quot;,&quot;copy_link&quot;:&quot;Copy link&quot;,&quot;edit_profile&quot;:&quot;Edit profile&quot;,&quot;follow&quot;:&quot;Follow&quot;,&quot;follow_back&quot;:&quot;Follow back&quot;,&quot;following&quot;:&quot;Following&quot;,&quot;like&quot;:&quot;Like&quot;,&quot;loading&quot;:&quot;loading...&quot;,&quot;reaction&quot;:&quot;Reaction&quot;,&quot;report_abuse&quot;:&quot;Report abuse&quot;,&quot;search&quot;:&quot;Search&quot;,&quot;success_settings&quot;:&quot;Successfully updated settings.&quot;,&quot;counted_organization&quot;:{&quot;one&quot;:&quot;%{count} organization&quot;,&quot;other&quot;:&quot;%{count} organizations&quot;},&quot;counted_user&quot;:{&quot;one&quot;:&quot;%{count} person&quot;,&quot;other&quot;:&quot;%{count} people&quot;},&quot;not_following&quot;:&quot;You&#39;re not following anyone&quot;,&quot;following_everyone&quot;:&quot;You&#39;re following %{details} (everyone)&quot;,&quot;you_are_following&quot;:&quot;You&#39;re following&quot;,&quot;and&quot;:&quot;and&quot;}}}"></div> <div id="reaction-category-resources" class="hidden" aria-hidden="true"> <img data-name="Like" data-slug="like" data-position="1" src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18" /> <img data-name="Unicorn" data-slug="unicorn" data-position="2" src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18" /> <img data-name="Exploding Head" data-slug="exploding_head" data-position="3" src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18" /> <img data-name="Raised Hands" data-slug="raised_hands" data-position="4" src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" width="18" height="18" /> <img data-name="Fire" data-slug="fire" data-position="5" src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18" /> </div> <script> var userSignedIn = false; if (document.readyState === 'complete' || document.readyState === 'interactive') { initAuth(); } else { document.addEventListener('DOMContentLoaded', initAuth); } function initAuth() { var paramToken = new URLSearchParams(window.location.search).get('jwt'); if (paramToken && !userSignedIn) { authenticateUser(paramToken); } else { var iframe = document.createElement('iframe'); iframe.style.display = 'none'; iframe.src = 'https://forem.com/auth_pass/iframe'; document.body.appendChild(iframe); window.addEventListener('message', function(event) { if (event.origin !== 'https://forem.com' && event.origin !== window.location.origin) { return; } var data = event.data; if (data.authenticated && !userSignedIn) { authenticateUser(data.token); } else if(data.authenticated && window.ReactNativeWebView && window.ReactNativeWebView.postMessage) { window.ReactNativeWebView.postMessage(JSON.stringify({ action: 'login', token: data.token, })); } }); } function authenticateUser(token) { fetch('/auth_pass/token_login', { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': getMetaContent('csrf-token'), }, body: JSON.stringify({ token: token }), }) .then(function(response) { return response.json(); }) .then(function(data) { if (data.success) { if (document.head.querySelector('meta[name="user-signed-in"][content="false"]')) { // Reload the page to update the user's state location.reload(); } } }) .catch(function(error) { console.error('Error during authentication:', error); }); } function getMetaContent(name) { var element = document.querySelector('meta[name="' + name + '"]'); return element ? element.getAttribute('content') : ''; } } </script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10