Category: JavaScript

  • Imagining a WordPress Greenfield

    Just suppose, just for a moment, that you and I were tasked with creating something every bit as wonderful as the wonderful parts of WordPress, but starting with a (mostly) blank slate.

    It’s the plugins

    Well, one thing we have to get out of the way right away is what to do about the huge number of useful plugins that are the particular strength of the WordPress platform. Do we want to walk away from the ecommerce plugins, the learning management kits, the membership tools?

    If we want our cake and the eating of it, we’ll have to reckon with the immutable fact that all of that stuff is written in PHP and it all runs on the server. There are no lambda plugins. There are no client-side plugins.

    And it’s PHP. Some folks argue that PHP is antiquated, but I think that’s about fashion more than sense. It’s a fairly sophisticated language, performant, all that.

    All JavaScript?

    But as long as we’re declaring a fresh start, you’ve got to reckon with the hard truth that PHP doesn’t run on clients. Essentially, JavaScript is the only choice in that regard. And if you’re running JavaScript on the client, it makes life a lot easier to be running the same language up on the server.

    If we change gears and use Node.js on the server, then the challenge is finding some way to continue using existing plugins.

    I’ve turned this over and over in my mind. On the one hand, it seems pretty likely that a WordPress-specific translator could be built to turn plugins in Node.js plugins. If we do that, though, then we have to support all the action and filter hooks.

    So, on the other hand, maybe what we want is to make it easy for plugin providers to rewrite their code bases anew. Assuming an approach that was generally similar to WordPress’s approach, developers would have a pretty good sense of how they should approach various tasks.

    For example, you’d probably want get_current_user() to be getCurrentUser() and you’d probably want it to return a user ID. And you’d want to have roles and the roles would be collections of capabilities.

    Post much?

    That’s easy enough (maybe), but do we really want to commit to preserving the concept of everything being a post? We’d have to give that one some thought, but maybe the easiest way forward is to stick with posts and pages and custom posts and such.

    There’s a lot of complexity in core, though, the inevitable result of organic growth over twenty years, and maybe we just carefully sort through and discard a lot of the baggage that still works but probably was never such a great idea. And maybe we tack on a new concept or two, like having a React-like routing system be the default.

    But what we want is for WooCommerce defectors to have a straightforward sense of how to write a new and significantly more straightforward ecommerce solution. NewCommerce?

    Astro adoption?

    There’s another question to consider: given the complexity of building this sort of system, possibly the best way forward is to start with an existing system and then add on whatever stuff is needed to support critical plugin rewrites.

    This is the line of thought that has landed me at the front door of the Astro community. If you’re unfamiliar with Astro, it does content sites, like our friend WordPress. And it’s server centric, like WordPress. But it’s also vastly newer and thus not yet covered in all those rustic barnacles.

    It appears to have themes. It doesn’t, as far as I can tell, have plugins in the sense one has them in WordPress, but it seems at least conceivable that an interface to a plugin system could be created. It doesn’t have an in-built editor, but again, that seems like something that could be whipped up. Or, in a funny little twist, I feel pretty darned confident that the WordPress block editor could be pressed into service.

    So I’m going to explore Astro. Not because I’m so convinced that the current troubles in the WordPress world are going to lead to WordPress falling apart, but because I think we all need to think about hedging our bets. And, frankly, because there may be better options out there in the blog-and-content-creation universe.

    So, more to come on this. One clear takeaway, though, is that WordPress has built up an enormous and enormously useful ecosystem and feature set over the years. Leaving would be painful.

  • Headless WordPress and why it matters

    You know there’s headless WordPress, but may not be clear on how you’d make it happen. Or, more importantly, why you’d make it happen.

    What is headless WordPress?

    Let’s start with a quick rundown of what makes a WordPress site headless, why the naming in this case is exactly backwards, and just generally get ourselves on the same page.

    The conventional headful approach

    Normal WordPress is a world in which the action happens on the server. A website visitor requests a page from the server and the server assembles the page components (header, body, footer) from the database and any relevant templates. This is sent to the browser, any browser at all. And if something happens down there on the browser, it will result in a new page being requested from the server.

    Where this basic operation is perhaps most clearly visible is when the site provides some kind of data application. Maybe it’s a CRM application, so you might request a list of clients in the system. You get a display of the first 25 of them from the server, say. If you want to see the next page of clients, a new page will be requested from the server. If you want to see a particular client, a new page will be requested to display that client’s information. If you change the information for that client and want to save it, you’ll submit a form to the server and a new page will be delivered to show the update.

    Meanwhile, in the rest of the universe

    For most of the rest of the web, this isn’t typically how an application works, however. If you start with an application that shows a list of client records, then when you want to see the next page of them, a request will be sent to the server to retrieve only the data for the clients that need to be shown. The page with the client list won’t be replaced; rather, the new set of clients will be displayed on the existing page where the previous clients were listed.

    It’s possible that you can edit any of the client fields you can see on each row of the listing. Let’s say you do this and press a save icon at the end of the row you’ve changed. Again, this doesn’t result in a new page being requested. Instead, the listing continues to show the change you made and the change is sent as an update request to the server.

    The server, in other words, is just supplying data at this point, not pages (though, in our scenario, it probably supplied the initial listing page).

    Decouple this

    There are two things we should notice about this scenario. First, there’s got to be some kind of back end that answers requests for data and updates, even if it’s not supplying the pages. Second, the pages still have to come from somewhere. But the pages and the data don’t really have to come from the same place, and thus we can say that the presentation and the data have been decoupled.

    When you decouple the head of a thing, well, it becomes headless. So the baseline idea of headless WordPress is that there’s a WordPress server running, but it’s not supplying the pages that the website visitor is seeing.

    So where are the pages coming from? That depends, but most scenarios out there on the web right now fall into the basic pattern of using React (or some React framework that extends React) to create pages that can be retrieved from web servers as plain HTML and JavaScript files. These pages aren’t assembled or calculated on the server end, they are simply sent to the client as they stand. You’ll hear these scenarios referred to as static sites. That’s because the server doesn’t muck around with them–they can be plenty active once they are displayed in a browser window.

    One question that may already have popped into your mind is: what is React? And that’s an excellent question, but not one that we’re going to answer in any detail here. Suffice it to say, it’s a pre-built set of capabilities implemented in JavaScript, where the capabilities mostly have to do with user interactions.

    The key thing is that JavaScript and React are capable of asking the server (or more than one server) for data that it needs to display. The server that sends the data down to the browser in the headless WordPress scenario is, you guessed it, a WordPress server.

    Headless

    There are plenty of headless scenarios where the server isn’t a WordPress server and there are even scenarios where there arguably isn’t a server in the traditional sense.

    But we’re talking WordPress here. In that scenario, there are two primary ways that WordPress might interact with whatever’s going on down there at the browser window. It may, in the older and more widely adopted approach, use a REST API to make requests for data (or requests to place or update data on the server). Making a REST call is based on requesting a particular URL and it either places any changeable data at the end of the URL (as parameters) or it arranges them in the same way you might arrange data when posting a form to a web server.

    The other approach out there these days involves using a Graphql interface. This is more like opening a window directly into a database and making queries. The details of this don’t much matter for this discussion, the point is that it’s possible to install a plugin that creates a Graphql access point for a WordPress site.

    Wait, but why?

    Why would you take this headless approach, though?

    The obvious first answer is that it enables you to have a different language and framework running on the client side of things. If you want a React application that serves up a lot of server-side content, using WordPress as your CMS might very well make sense.

    Additionally, though, it gives you the capability to render and rerender a page in sections, so that you aren’t necessarily requesting a whole new page from the server every time anything happens.

    Now, as it happens, you can pull off this same trick using the new Interactivity API in WordPress, because it makes the front end capable of doing various things on its own. It let’s you build a “headless-seeming” user experience completely within a WordPress context.

    It’s not clear yet how well the Interactivity API will fare, as it’s still relatively early days, but it’s an interesting option for dynamic front ends (plus it’s in use within WordPress core, so it’s not likely to go anywhere anytime soon).

    WordPress makes a pretty solid CMS, particularly where the content is of the human-readable sort.


  • AI Coding and Context

    It’s clear that the way to get code “as if you’d coded it yourself” is to include your coding in the context that your LLM is using. Cursor, which I’ve been experimenting with of late, gives you several layers of potential customized context, and I finally found a few minutes to explore how this works.

    In case you’re wondering, Cursor is a new kid on the block and the documentation is correspondingly minimal. Note, though, that you can simply ask the AI for an explanation…

    A screen clip where the AI is prompted about setting context and replies that it can't "directly help with Cursor's functionality"

    Oops…actually it doesn’t include Cursor itself in its context. I’m not actually knocking this — it makes sense from a context management point of view.

    how can it not know what it is?

    Anyway, the basic idea is that there are some @keyword directives that allow you to include things in the context of the current chat (and, of course, different chats can and will use entirely different contexts.

    So if you type @ in your chat window, you get a list of options that includes @folders, where it suggests the current working directory, but you can put anything you like in there, folder-wise. Interestingly, it will tell you if it doesn’t think you’ve picked useful files for context:

    Looking at the code, I don't see any files that would be relevant to the user meta functionality we were discussing. The files shown are mostly block-related files from the pzdata plugin, containing JSON configurations, CSS styles, and asset dependencies.
    
    To properly help with the user meta issue, we'd need to see:
    
    The file where get_user_help_preference() is defined

    The world inside an AI-powered IDE is a weird place, though. Consider, for example, that it was Cursor’s AI (channeling claude-3.5-sonnet) that wrote get_user_help_preference() in the first place.

    For my own purposes, I want to be able to say, listen, when asked to add this or that capability or configuration to the program in question, please solve it using this algorithm, inside a function named according to this pattern, and invoking this function from this kind of callback.

    Straight out of the box it seems pretty darned good at figuring out that it should follow your naming conventions (though I suspect this relies on your having been disciplined about following them yourself), but what about making it expect to be on the business end of a callback?

    Intriguingly, there’s an @ directive for @docs. As is the case absolutely everywhere in the documentation, the explanation of what it does is pretty sparse: you can point it at the documentation for…whatever you like. They are assuming regular framework or library documentation, things like the docs for NextJS, but presumably you could try adding something like a coding standards document or rules like “make these changes by hooking the ‘init’ event and making this a callback function.”

    I thought there might be a deeper dive into this in Cursor (the company)’s blog, but things are pretty sparse there, as well. That’s not a knock, either–these folks are busy making the donuts. It’s interesting to read their post of a year ago about the problems they hope Cursor will solve. The vast majority of what they’re taking on is, in one way or another, a question of managing context (or to put it another way, managing tokens).

    Just to give this a preliminary once around, I created a file in my current project called instructions.txt:

    If you are asked to create a function called "my_response()", make it a function that writes a short message to console.log.

    No sooner had I saved this than it (because it was in the current working directory, which I’d included in its entirety) was picked up and my edit window was prompting an edit completion for the function header, but I could also use the “generate” option in the editor, where I asked for a function with the magic name:

    a chat box asking for a function called "my response" and offering the complete function as an update.

    It’s a trivial case to be sure, but oh my god does this seem promising.

    (Final note: I don’t think I’ve ever used a meme GIF in my writing before. I don’t know what came over me.)

  • A WordPress Client Dashboard

    Just to be clear right up front, this is not an article about customizing the back-end dashboard that WordPress provides to system administrators. This is an article that captures my journey in creating a WordPress client dashboard to show various kinds of statistical progress to PeakZebra clients. These folks don’t care how many page views the PeakZebra.com site is getting. They care about monitoring how things are going in their consulting engagement with me.

    When someone becomes a PeakZebra client, typically they are working on a content marketing project. As often as not, they’ve been browbeaten about how important SEO could be to them and they feel a little guilty about not having done much of anything about it.

    So the first useful thing PeakZebra can provide them is a specific plan for content and for whatever SEO benefits we think might be realistically achieved in the coming year (the world is filled with people who wildly overpromise what can typically be achieved with SEO, but that’s an article for another day).

    That plan is stored on PZ, accessible only to them through their client login. Additionally, I want clients to be able to see how things are going month over month. And my experience has been that almost all the details I care about in SEO program execution are things they simply do not have time or energy to be bothered with. So I need to show how things are going and do it sticking only to the most useful metrics, showing them in a visual format that makes them very quick to digest.

    What I need, in other words, is a WordPress client dashboard. You know, green light if things are good and let’s hope the light is never any other color than green.

    This turns out to be relatively simple to achieve, but maybe not quite as simple as you’d think. Today’s article brings you the gory details of the first pass I took at this, working within the context of the Divi page builder for WordPress. In a follow up coming in the next few days, I’ll walk through the path I took after I decided I needed better graphic and table tools, which then meant I didn’t really want to use Divi because I was happy with the look without it.

    Easy-does-it WordPress Client Dashboard

    To make things easy, at least initially, I decided that the dashboard wouldn’t directly query data in realtime. Rather, there would be tables on the site that were periodically updated, and it’s the data from the tables that winds up displayed in the dashboard.

    Second, I absolutely needed to prevent a client’s dashboard from being visible to anyone but the client and myself (and authorized contributing team members). I wanted to keep that simple as well, about which more toward the end.

    One final thing for simplicity’s sake the first time around: I’m just going to make each client’s dashboard a regular WordPress page. That way the dashboard pages are just ordinary pages, meaning I can throw in whatever page components I like (assuming we’re using Gutenberg or a page builder like Divi).

    This isn’t really how I think this should be done. Rather, the “real” way to do this is to create a custom post type, probably called “dashboard,” with each client having a post of that type. That’s by no means complicated, but we’ll hold off for now.

    Data

    In order to show the data, we need a plugin that, ahem, turns data into pretty charts. And I want to stress here: if you’re bothering with charts, pretty is almost certainly a hugely important part of the deal. We want pretty.

    There are a bunch of plugins out there that will take data and spit out charts. The popular page builders that web designers often use with WordPress these days also have at least some elements that lend themselves to showing data, which is what sent me down this initial route to have a look at what the Divi builder (the one I have the most experience with) could do.

    Mixed results, honestly. To be sure, I can build a Divi dashboard that looks pretty darned good. But I did have to hunt down a couple of extra tools to get it done.

    All by itself, you can’t do much that looks “dashboard-y” in Divi. It will let you show numbers as a single bar, as you see here:

    You get as much satisfaction out as you put effort in.

    And you can throw in animated circles with numbers in the middle of them, of the sort that you’ve seen on a million landing pages:

    It’s almost the answer to the universe.

    Honestly, I think they both look nicely professional, but we’re going to need some more stuff, goodles like bar charts and spider graphs and maybe color-coded maps.

    Send in the Charts

    In fact, you can get these in Divi by investing less than ten bucks (assuming you already have a Divi license, which is a larger expense) in an add on available through the Divi Marketplace. In the interest of responsible journalism, I picked this up and gave it a whirl:

    Peace is the thing with feathers.

    In addition to this line chart, there are six other chart types—all basic stuff like pie charts—and each of the chart types has some degree of animation and interactiveness, such as popups that show the values on the line as you hover over them. You can flip the chart into several different predefined palettes, or override the CSS to set your own colors, or go with monochrome.

    It’s actually not bad, except for one thing… Putting the data in is a bit clunky, in that you bring up the properties box for the graph and then input comma separated values for each data plot. It’s not terrible for something with a dozen data points, but you’re not going to want to do anything big or fancy with this.

    The only way to update the data is to go back into the properties and hand edit (or paste over) the data. This seems like a deal killer for many sorts of projects, where you’d like to suck up a spreadsheet in one go, or maybe query a REST API for the latest data.

    If you need something that’s very top-level and that you can just edit now and then as the need arises, you could build a pretty professional-looking dashboard with this.

    This won’t help you if you need to place tabular data somewhere in your dashboard, of course. For that, the simple answer (with or without Divi being involved) is the TablePress plugin.

    I like TablePress. It’s a robust, simple tool. You can get the data you want from a .csv or Excel file (and from a couple other source types as well), suck it up to your WordPress site, where it’s assigned a shortcode, then embed the shortcode in the page where you’d like it to appear. The results look pretty decent as long as you don’t have too many columns. Too many columns makes for a complete mess.

    You can embed a shortcode directly into a Divi page, no problem, and that includes TablePress charts.

    If the table you get from TablePress by itself, though, isn’t dressy enough to suit you, it’s possible to add in an additional plugin called TablePress Styler, sold at Divi creator’s ElegantThemes.com website for $35. I haven’t really dug into it, but I suspect that most of the things that TablePress Styler does are done simply by manipulating the CSS associated with classes that are set up in TablePress itself. Meaning you could do lots of the styling yourself for free.

    But TablePress Styler makes short work of making a table look quite fancy, no question. If you’re going this route, I’d recommend it.

    Except…you might want to handle your tables with the Visualizer plugin, which will give you both charts and basic table capabilities. The free version gives you six chart types; popping for a $99 “personal” license gets you an additional nine chart types, email support, and periodic synchronization with either .csv files or JSON endpoints (full pricing information is here).

    This last part—the data sync-ups—strikes me as the thing that might make it worth a hundred bucks. If you set it up using this feature, you can update your underlying spreadsheets and not worry about the dashboard keeping up, because it will do that on its own.

    By this point, though, the bulk of the dashboard is being supplied by plugins that have nothing to do with Divi. So whether you bother with Divi (or Elementor, or any other page building tool) really comes down to how much control you want over the design of whatever else is on the page, whether you want fly-in graphics or accordions with icons that rotate as the sections are revealed and all that other “fancy professional design” stuff.

    By the time you get the charting and table plugins involved, it’s kind of an incidental detail that the page was made in Divi. Indeed, the argument could be made that Divi isn’t really doing all that much here. If you get the sense that I’m about to abandon the Divi approach, you’re probably right.

    So, yes, to be clear: I by no means want to imply that Divi is the way to do a dashboard. Truth be told, Divi can be pretty quirky (though it can also produce beautiful WordPress results) and there’s some question about which of the WordPress builders will survive the introduction of blocks as the essential design element of WordPress running natively (which, roughly speaking, makes WordPress itself a page builder).

    To get the same sorts of graphs I discussed up above, you can use any of a number of WordPress plugins, some of which provide block support. A walkthrough of this approach is coming in a week or so.

    And, yes, I did say I’d talk about gating access to the dashboards so that only the client can see that client’s dashboard. The short answer is that you can do it using the PublishPress Permissions plugin. There’s also another approach with fewer moving parts—next time…

  • A Solidity Definition

    If you’re keeping an eye on Blockchain, you may have run across mentions of “solidity” as part of discussions of the Ethereum blockchain, and in particular alongside discussion of smart contracts. Any solidity definition is going to lead you straight into the topic of smart contracts and this post is no exception.

    The smart contract concept was always part of Ethereum, but Solidity as a programming language in which to create those contracts dates back to 2014, when it was proposed by British software developer Gavin Wood. Work on realizing the proposal was carried out by Wood along with contributors including Christian Reitwiessner, Alex Beregszaszi, Liana Husikyan and Yoichi Hirai.

    Solidity is now one of several options, including Serpent, Viper and Mutan, for programming on the Ethereum blockchain, which functions as a sort of ‘global computer.’ As a computer, Ethereum runs low-level instructions on the Ethereum Virtual Machine (EVM). All of these languages compile to bytecode that is native to the EVM.

    While Solidity was originally conceived as a programming tool for the Ethereum blockchain, it runs in other blockchain environments as well, including:

    By design, Solidity bears a strong resemblance to ECMAScript (the latest version of JavaScript) and, by extension, languages derived from C. The language uses strong typing and supports object oriented programming, including class inheritance.

    Solidity enables you to write applications that are written to the Ethereum blockchain. These applications implement self-enforcing contractual agreements (that is, “smart” contracts). In a smart contract, funds and assets are automatically controlled and distributed based on parties to the agreement meeting specific conditions.

    The primary benefit of such smart contracts is that business transactions can be carried out without a third-party mediation of the terms. If a payment must be made before a digital asset is released to a party to the agreement, for example, the contract itself can verify that cryptocurrency has been transferred to the contract and then automatically release the asset. Smart contracts can also be used to control minting of new creator coins within sidechains according to demand and price stability, meaning that prices can’t be manipulated by the creator supported by the creator coin once the contract controls are in place.

  • Gatsby rolls out functions, “shifts left”

    Gatsby (the company) held a “summer camp” online earlier today and used the occasion to push the new “functions” capability into general availability. Functions is interesting in and of itself, but equally interesting was the way that Gatsby, and product director Dustin Schau (@SchauDustin ) in particular, were talking about what the rollout meant for Gatsby (the framework).

    Pointing out that “rich web experiences are now the norm, not the outlier,” Schau went on to say that this “relies upon dynamic functionality.

    Whoa, that’s dynamic…

    This marked a change in tone from the usual “make some API calls if you really must have dynamic functions” train of thought in the larger static web site community. Schau went on to say that there’s a spectrum ranging from all dynamic to all static and Gatsby is “shifting left” toward more built-in dynamic support.

    The trick to all this is, no surprise, the support for functions. I haven’t dug in and tried to do things with functions yet, but there’s definitely a nice clarity and neatness to the basic idea, which is that if you write and export a function in a file that you’re storing in the “api” subdirectory you’ve created in your “src” directory, this function will be run at the network edge at runtime. So, to take a minimal example, if you create a function that returns the current time, it will execute when the user is looking at the page that renders it, will run right then and there, and will display the actual current time in the browser.

    You don’t need a function to get the current time displayed, but stop for a moment to think about how clean the basic setup is.

    In one of these functions, you have to take care of two variables that are passed in, the first being Node’s request object and the second being Node’s reply object. This, roughly speaking, means you can easily act like you’re dealing with a POST or GET request and spit your results back out as a reply. You can also redirect fin the reply object, which is a clean way to chain together different functions.

    Developing with Gatsby Functions

    You can test sites with functions in your local environment—it works with versions of Gatsby from 3.7 up (which is roughly as of the very latest available version, at least as this is being written). If you deploy using Gatsby Cloud, yup, it just works. Netlify (which has its own function capability that’s not Gatsby specific) has also added support for Gatsby functions, so that works too.

    This really is a different animal than what we typically might call an SSG. At the same time, it’s not the same thing as just throwing up a server on the back end to handle the dynamic stuff. Pushing the dynamic functions out to a serverless edge compute scenario gives you inherently faster performance for dynamic features, gives you the same inherent “magic” scalability that you get by running static sites on CDN’s, and for me at least, it raises some questions about how data is synchronized across, say, an enterprise application.

    To put it another way, I don’t yet entirely understand where the data comes from, though presumably its accessible using the exact same mechanisms you’d normally think of within React. But… from where? I’m sure it differs by application and whether you have any margin for slightly stale data.

    More to explore in this regard, and I’ll follow up when I know more.

    Gatsby says recordings of the presentations (there was more than just the function announcement, including a nice demonstration of putting together a few functions who’s patterns you’re likely to encounter in typical applications) will be up in a few days. The demos are worth checking out. I’ll update with a link when they’re up.

  • GatsbyConf 2021 brings new 3.0 version and new images

    Latest revision: March 4, 2021

    The online virtual GatsbyConf, which kicked off today, announced at least six significant updates, including a 3.0 release of Gatsby itself; a new component that goes beyond the already savvy Gatsby-sharp handling images used within Gatsby sites; and the addition of a CDN service (in partnership with Fastly) to the Gatsby Cloud service. Additionally, there were new, substantially changed releases of key plugins tying Gatsby to headless instances of WordPress, Shopify, and Contentful.

    Patrick Sullivan, Senior Product Manager at Gatsby Core Team, noted that the past year has seen a 40% increase in the number of Gatsby sites on the web, but conceded that there were “a number of struggles with using Gatsby.” Toward addressing issues such as build times, especially as part of the local developer experience, Gatsby Senior Software Engineer Lennart Joergens walked through two significant updates being released as part of 3.0. First, local development warm rebuilds will use a “query on demand” capability so that only altered pages are regenerated.

    Joergens showed a second change where the directory structure of content in a site can be mapped onto the source file directory tree. You might have a “products” directory, a “shirts” directory within it, and then the slug for each file will reflect a product name. This is the sort of organization good developers tend to lean toward in any case, but here the logic that’s encapsulated in the setup can be combined with the partial rebuild capability so that, as Joergens demonstrated, changing the name of a shirt product causes several pages to rebuild (because there are links on other shirt pages to this product along the lines of “you might also like”), but changing the description on the shirt page causes that page only to rebuild, because that’s the only place where that text is rendered.

    Online resources relevant to 3.0:

    The Chasm

    More than one speaker in the conference lineup—and this includes Product VP Dustin Schau —talked about website creation as a function of two presumably rather different groups: marketers (for the words on the pages in the site), and developers and designers (for the site itself).

    Nick Gernert, CEO of WordPress VIP (the high end consulting and hosting arm of Automattic), took the position that the JAMstack world has been too focused on tools to grease the skids for developers (and enhancing performance), but would need to shift the priority to enabling creators (that is, the marketers). He proposed a website version of Maslow’s Hierarchy of Needs, where the base of the pyramid is Security and Scalability, and the peak is the “meaningful content experience.” Just below the peak? Agility.

    Seize (and Discard) the Moment (Library)

    One final takeaway: more than once in presentations during the day, the moment.js library was called out as something that, when used, causes an outsize bump in the size of your JavaScript bundles. You’ve been warned.

    A second day of the conference will offered several workshops, including a 101 course to get yourself started with Gatsby.

  • The Core Web Vitals Report

    [et_pb_section fb_built=”1″ _builder_version=”4.8.1″ _module_preset=”default” custom_padding=”||7px|||”][et_pb_row column_structure=”3_5,2_5″ _builder_version=”4.8.1″ _module_preset=”default” min_height=”711px” custom_margin=”|auto|0px|auto||” custom_padding=”||0px|||”][et_pb_column type=”3_5″ _builder_version=”4.8.1″ _module_preset=”default”][et_pb_text module_id=”section1″ _builder_version=”4.8.2″ _module_preset=”default” custom_padding=”9px|||||”]

    Google’s Core Web Vitals: Executive summary

    [/et_pb_text][et_pb_text admin_label=”#section1″ _builder_version=”4.8.2″ _module_preset=”default” text_font_size=”19px” custom_padding=”5px|12px|9px|12px|false|false” border_radii=”on|1px|1px|1px|1px” border_width_all=”1px” box_shadow_style=”preset2″]

    [dropcap]G[/dropcap]oogle earlier pre-announced a May 2021 shift to using what it calls “Core Web Vitals” (CWV) metrics as part of its ranking algorithm. The pandemic has pushed this plan out to an unknown future date–Google has said it will provide six months further notice before the change is made. This report offers an initial explanation of the three metrics involved, how they relate to other Google page experience metrics, and how to strategize for what will likely be a noticeable effect on rankings when CWV enters the ranking algorithm.

    [/et_pb_text][et_pb_text admin_label=”#section2″ module_id=”section2″ _builder_version=”4.8.2″ _module_preset=”default” text_font_size=”19px” custom_padding=”||1px|||”]

    [dropcap]T[/dropcap]he fact that Google is changing its ranking algorithm is not, in itself, cause for alarm. Google changes its process—what gets measured, how it’s weighted, and so on—all the time. Generally there are several hundred (mostly trivial) changes in a year.

    CWV promises to be one of Google’s bigger deal changes. How much bigger is worth contemplating. We’ll get to that.

    One indication that this one matters to Google (besides the lengthy advance notice) is that CWV is an addition to a group of metrics that Google puts into the category of Page Experience. How does a user feel about the experience of using a particular page?

    As you can imagine, Google wants to send you to results that you are happy you were sent to. So, if you asked a question, they’d like to send you to a page that answers your question (or, better yet, they’d like to answer your question right there on the search results page). Beyond the content of the page, though, lots of things figure into how you experience the page you’ve just been sent to.

    If the page takes forever to load in your browser, odds are you won’t even stick around to see the page. But speed comes in more than one flavor, and CWV tries to get at a few elements that are important in how you perceive the speed of a page.

     

    [/et_pb_text][et_pb_text module_id=”section3″ _builder_version=”4.8.2″ _module_preset=”default”]

    The Core Web Vitals: What Are They?

    [/et_pb_text][/et_pb_column][et_pb_column type=”2_5″ _builder_version=”4.8.1″ _module_preset=”default”][et_pb_toggle title=”Toc” _builder_version=”4.8.2″ _module_preset=”default” inline_fonts=”Encode Sans Expanded”]

    Executive Summary

    Algorithm Changes

    What Are the Core Web Vitals?
    How to Get CWV Scores
    Do CWV Scores Matter?
    CWV Strategies

    [/et_pb_toggle][/et_pb_column][/et_pb_row][/et_pb_section][et_pb_section fb_built=”1″ _builder_version=”4.8.2″ _module_preset=”default” custom_padding=”0px|||||”][et_pb_row column_structure=”3_5,2_5″ _builder_version=”4.8.2″ _module_preset=”default”][et_pb_column type=”3_5″ _builder_version=”4.8.2″ _module_preset=”default”][et_pb_text _builder_version=”4.8.2″ _module_preset=”default” text_font_size=”19px”]

    [dropcap]C[/dropcap]ore Web Vitals (CWV) is a set of three measurements Google has said it will add to the group of measurements it uses when deciding which results you see first when you perform a search on Google. The decision to add these metrics was announced months in advance (something Google only very rarely does), was originally slated for May 2021, but has been pandemic postponed. Google has said it will provide six months of warning before pulling the switch and, as I write this, that hasn’t been given yet. So, perhaps late fall 2021.

    Google says there are three “core” essentials.

    The first measurement is how long it takes for the largest piece visible on the page in your browser (what’s “below” your window doesn’t matter until you scroll down to it) to appear. This is the “Largest Contentful Paint” (LCP) and it’s really just a proxy measurement. If you can get the biggest piece displayed in a hurry, probably the overall sense the user gets is that the page loaded in a hurry.

    How you can tell a page is performing in LCP measurements is something we’ll return to later—it takes some tooling.

    Measurement two is how long the user has to stare at the browser window before it will react to their input. How long before they can click on a button and something actually happens. This is First Input Delay (FID).

    Making things slightly more complicated, there are testing situations where Google uses a metric called Total Blocking Time (TBT) as a proxy for FID. For the moment, let’s not split hairs. What Google is trying to get at is how long before the page is sufficiently loaded that you can actually use it.

    The third measurement is largely targeting the mobile experience and focuses on the weird jittery effect you get when a page has started to paint, but some big piece drops into place and the page is repainted in a way that makes everything shift position all at once. You’ve started to read the page, but now everything shifts up a paragraph. It’s kind of hard to explain, but everyone with a smart phone knows what this is. Google measures it with Cumulative Layout Shift (CLS). Not just “does it jump,” but how much overall does it jump before it settles down and stays put.

    [/et_pb_text][/et_pb_column][et_pb_column type=”2_5″ _builder_version=”4.8.2″ _module_preset=”default”][et_pb_text _builder_version=”4.8.2″ _module_preset=”default” custom_margin=”167px|||0px|false|false” custom_padding=”14px|20px|14px|20px|false|false” custom_css_main_element=”padding: 10|| ” border_width_all=”3px” border_color_all=”#7CDA24″ border_style_all=”groove” box_shadow_style=”preset2″]

    THE “OTHER” WEB ESSENTIALS

    As mentioned, there are three “core” essentials. But there are four other metrics that Google considers “essential”:

    • Being “mobile friendly”
    • Being safe to browse
    • Using HTTPS
    • Avoiding Intrusive Interstitial ads and notices.

    You’ll notice that this is more a list of do’s and don’ts. You’re either using HTTPS or you’re not, for instance. 

     

    [/et_pb_text][/et_pb_column][/et_pb_row][et_pb_row column_structure=”3_5,2_5″ _builder_version=”4.8.2″ _module_preset=”default” locked=”off”][et_pb_column type=”3_5″ _builder_version=”4.8.2″ _module_preset=”default”][et_pb_text module_id=”section4″ _builder_version=”4.8.2″ _module_preset=”default”]

    How to “See” the CWV Measurements

    [/et_pb_text][et_pb_text _builder_version=”4.8.2″ _module_preset=”default” text_font_size=”19px”]

    [dropcap]G[/dropcap]oogle provides several tools that let you see specific scores for CWV, but probably the quickest way to get a general sense of how a given page is performing is to use the Pagespeed Insights tool. You paste in the URL of the page you’re interested in, it chews on things for a moment or two, and then two color wheels pop up, most likely sporting the red or orange rings that indicate a less-than-fabulous score.

    You’re generally going to want more detail than this score gives you, though. You’ll want to know what element is the one Google is counting as the largest when it times the Largest Contentful Paint, to give one example.

    Getting the info is as simple as going to the page you’re interested in using the Chrome browser, then toggling yourself into the developer tools pane (use the keystroke combination Ctrl+shift+i, which I think maybe stands for “inspection”).

    [/et_pb_text][et_pb_image src=”https://peakzebra.com/wp-content/uploads/2021/02/inspection-console.png” title_text=”inspection-console” _builder_version=”4.8.2″ _module_preset=”default”][/et_pb_image][et_pb_text _builder_version=”4.8.2″ _module_preset=”default”]

    Here’s the developer tools console in action, after recording the load of a page on PeakZebra. Following the timeline in the middle of the display is a great reminder that a lot of things are going on under the hood of a modern browser.

    [/et_pb_text][et_pb_text _builder_version=”4.8.2″ _module_preset=”default” text_font_size=”19px”]

     

    [dropcap]I[/dropcap]n the “Timings” bar in the top pane of the image above, the LCP flag marks the spot in the timeline when the Largest Contentful Paint was rendered in the viewport (in this case, at 2747.9 ms).

    Total Blocking Time (which will become important to us because it’s a proxy for First Input Delay) is recorded (as an estimate, though it’s given in hundredths of a millisecond, which I’ll concede is puzzling) just above the lower (console) pane of the tool display. In this case, it’s 654.52ms. But as for what it actually is? Google’s process looks at the timeline for tasks that took longer than  50ms. For each, the number of milliseconds that the task ran after the 50ms mark is added together. The “long tasks” (as they are called) are highlighted in the timeline by red hashmarks and a red triangle in the upper right of the offending taskbar. Google wants you under 300 milliseconds, so this page kind of sucks.

    Cumulative Layout Shift is marked in the timeline with red bars where Chrome noticed things shifting. If you click on the red bar, the part of the page that is shifting will be highlighted for you. The damage that is done to your score is a special Google concoction that looks at the number of frames in which elements are shifting and the distance in pixels that they shift.

    This is a place where things can go screwy in a hurry. And elements may be shifting in ways that you are completely unaware of. On the page I’ve been looking at here, for example, I noticed that the title of the page is rendered first in the font it’s supposed to be in, then in a default font that the theme I’m using (this is in WordPress) overwrites, then rerenders as the font it’s supposed to be. The change in font means the title is longer in the default, so that it runs over to the next line, which shifts that segment of the page, though just for the shortest blink of an eye:

    [/et_pb_text][et_pb_image src=”https://peakzebra.com/wp-content/uploads/2021/02/text-paint-example-1.png” title_text=”text-paint-example” _builder_version=”4.8.2″ _module_preset=”default”][/et_pb_image][et_pb_text _builder_version=”4.8.2″ _module_preset=”default” text_font_size=”19px”]

    Everything returns to normal a millisecond later and, at least on a reasonably peppy system, this repaint is completely undetectable. The metric that matters to Google here is really more how it performs on a mobile device, but the change is undetectable there as well.

    At present, the CLS metric is less weighted in Google’s algorithms and the fact that they’re still sorting out how to detect what actually impacts the experience is presumably the reason why. They’ll get better at measuring this as the year progresses and it seems pretty likely that at some point the weighting will shift to make CLS equally important.

    [/et_pb_text][/et_pb_column][et_pb_column type=”2_5″ _builder_version=”4.8.2″ _module_preset=”default”][et_pb_image src=”https://peakzebra.com/wp-content/uploads/2021/02/low-pagespeed-performance.png” title_text=”low-pagespeed-performance” _builder_version=”4.8.2″ _module_preset=”default”][/et_pb_image][et_pb_text _builder_version=”4.8.2″ _module_preset=”default”]

    Here’s a meh score for a page on the WordPress version of PeakZebra. In truth, this score isn’t actually that bad and you’ll see considerably worse scores on many perfectly normal WordPress pages. This shows the desktop score; the mobile score is (and usually is) considerably worse. 

    [/et_pb_text][/et_pb_column][/et_pb_row][et_pb_row column_structure=”3_5,2_5″ _builder_version=”4.8.2″ _module_preset=”default”][et_pb_column type=”3_5″ _builder_version=”4.8.2″ _module_preset=”default”][et_pb_text module_id=”section5″ _builder_version=”4.8.2″ _module_preset=”default”]

    Do CWV Scores Matter?

    [/et_pb_text][/et_pb_column][et_pb_column type=”2_5″ _builder_version=”4.8.2″ _module_preset=”default”][/et_pb_column][/et_pb_row][et_pb_row column_structure=”3_5,2_5″ _builder_version=”4.8.2″ _module_preset=”default”][et_pb_column type=”3_5″ _builder_version=”4.8.2″ _module_preset=”default”][et_pb_text _builder_version=”4.8.2″ _module_preset=”default” text_font_size=”19px”]

    [dropcap]I[/dropcap]f you’re running on a typical WordPress, Drupal, or similarly architected web publishing framework, your CWV scores at present are probably not all that great. You are right to wonder whether fixing the ills of your website are worth the trouble. Will your rankings really suffer all that much if you don’t bother? What if everybody just decided to ignore this stuff?

    The only true answer to this at the current moment is: nobody outside of Google has any idea whether this matters much or at all. We’ll find out when and if there are huge reorderings on search engine results pages (SERPs).

    That said, if it figures in the rankings in any modestly significant way, you can bet that organizations that actively tune for SEO will tune for CWV. In any “all things equal” situation, their page is going to do better than the organization that didn’t bother. I’m operating mostly on an experienced hunch here, but I think there will be some serious shifts as a result, particularly in the world of B2B and technical vendor pages.

    [/et_pb_text][et_pb_text module_id=”section6″ _builder_version=”4.8.2″ _module_preset=”default”]

    CWV Strategies

    [/et_pb_text][et_pb_text _builder_version=”4.8.2″ _module_preset=”default” text_font_size=”19px”]

    There are four ways a company might opt to deal with CWV (aside from just ignoring it), listed here in decreasing order of hassle:

    1. Relaunch on a more performant platform
    2. Make substantial adjustments to the existing platform (really paying attention to tuning a WordPress site, for example)
    3. Use the existing website as a headless CMS for a statically generated front end to the site
    4. Create groups of new pages on the existing domain that run in tandem to the existing site, these pages being ones that matter to the organization’s content and SEO strategy

    [/et_pb_text][/et_pb_column][et_pb_column type=”2_5″ _builder_version=”4.8.2″ _module_preset=”default”][/et_pb_column][/et_pb_row][et_pb_row _builder_version=”4.8.2″ _module_preset=”default”][et_pb_column type=”4_4″ _builder_version=”4.8.2″ _module_preset=”default”][et_pb_text module_id=”section6″ _builder_version=”4.8.2″ _module_preset=”default”]

    How to Choose

    [/et_pb_text][et_pb_text _builder_version=”4.8.2″ _module_preset=”default” text_font_size=”19px”]

    Is it worth the trouble to, say, relaunch on a new platform? Hard to say at this point, and maybe not, but if you were going to relaunch something anyway, now is the time to make sure that whatever you relaunch with has screamingly good performance when it comes to CWV.

    Otherwise, your choice will come down to the specifics of your site and what it does. We can dig into the virtues and mechanics of the various options in future articles, but it’s certainly worth taking a few moments now to run a representative sample of your website’s pages against these CWV metrics.

      [/et_pb_text][/et_pb_column][/et_pb_row][/et_pb_section][et_pb_section fb_built=”1″ fullwidth=”on” _builder_version=”4.8.2″ _module_preset=”default”][/et_pb_section]

    1. TheJam.dev Day Two: Looks at Angular+Jamstack, Github Founder’s Take

      Key among the events at the second day of the Jam.Dev online event was the concluding “fireside chat” with RedwoodJS creator and Github founder Tom Preston-Warner, in which Preston-Warner imagined a more full-stack edge architecture, something he is working on RedwoodJS to create. (Coverage of day one is here.)

      Tom Preson-Warner

      Moderator Brian Rinaldi, developer advocate at StepZen, asked Preston-Warner what he thinks of the “Jamstack” terminology. “The term jamstack was coined by the founders of netlify and I got involved with them very early in their journey when I think it was just the two of them, Preston-Warner said. “The term jamstack was something we talked about a great deal at some bars in the Dogpatch in San Francisco when they were just setting out and trying to define what Netlify was going to be and where they were going and how do you talk about the ideas behind what we now know as the jamstack, without a term. At the time, before we had the term jamstack, it was all static site generators, but When you say a static site, this does not  necessarily convey that you’re going to use javascript to pull in third-party APIs, or do dynamic things, or pull in external content and kind of mix it all together. So ‘static site generation’ did not do the job.  … . So that’s where jamstack really came from, and I thought it was great.

      “It always makes me think of Ajax when google maps first came out and it blew everyone’s mind because you could drag this map around it will just load stuff in automatically. And this concept that Ajax became, it was out there, all the pieces were there but nobody thought about it and no one could really leverage it because no one could talk about it until Ajax was coined. And now this concept this more complex concept had a name and everyone could talk about how they were going to do Ajax. And to me jamstack is the same kind of a thing.”

      He went on to note that “the industry needed a name for what the jamstack is, this collection of technologies that allows you to have better security, faster sites, all of these characteristics that jamstack has are now wrapped up in one word that you can talk to your colleagues about, talk to your boss about, that Netlify can talk to their customers about.”  

      Rinaldi asked what RedwoodJS is providing that Jamstack isn’t providing yet. “I love Jamstack in the way that most people think about it today,” Preston-Warner said. “But I think it can go even further. There’s a lot of potential in what you can do in a serverless environment now and if you mix that with some of the ideas around static site generation and third-party apis, or even just javascript on the front end and the client talking to something, some kind of api on the backend. I think that’s cool, but what I want to do is create a custom website completely from scratch and probably not even use a lot of the third-party apis. I might pick and choose a few here and there, but I want to create a custom site that is doing a lot of its own business logic. So, being involved in Netlify, when they came out with their function support where you can write the body of a lambda function in a file and they’ll pick it up and deploy it to AWS Lambda for you. That was kind of a revelation for me in what could be possible using this stack, because nobody wants to use AWS’s ways to get your code into AWS Lambda. It’s just not pleasant.

      “You can push all of these things out as far to the edge as you can, and you can get a level of architectural simplicity and scalability for a tremendously small amount of effort. Thinking about that made me want to find a framework that was going to let me do that.”  

      Jamgular

      Another session concerned with somewhat alternative frameworks walked through a mix of Jamstack and Angular. The presenter, Netlify Developer Experience Engineer Tara Manicsic called the combination “Jamgular.” What was nice about the session was that it featured Tara on a highwire of live demonstration and viewers got a good view into what had to happen, complete with lots of detail, in the actual work of building and configuring an Angular project. The flip-side was that, as tends to happen with live coding, various things didn’t go as expected and, well, it was like real programming.

      A less-known detail that came forward was that Angular has built-in support for generating a folder containing the static output for a project, so even though Angular doesn’t come up as frequently in jamstack conversation, it’s definitely in the hunt.

      Manicsic was asked by an attendee why she’d mentioned in passing that redirects were important. The point here was that a user can request something using a URL that is redirected at the CDN edge and sent to an edge handler (a function running serverlessly at the CDN). The callback is made so that it includes data about the edge node where the call originated, so that geographically specific actions can be taken.

      Other Talks

      Gatsby Software Engineer Obinna Ekwuno gave a more philosophical talk about when it’s good to simplify architectures and when too much gets lost in the simplification. While he pointed to some interesting tensions between having to learn lots of frameworks and libraries to find one’s way through the jamstack world (and even more as the line between front-end and back-end blurs), it seemed like we are doomed to live with those complexities for the foreseeable future.

      Agility CMS President Joel Varty tackled what is surely one of the major questions that pops up around Jamstack front ends: where “everything else” goes – things like user registration, authentication, restricted access, user-generated-content, commerce and search. His talk met with lots of approval in the conference chat stream, insofar as it created a lot of clarity around the big picture of jamstack’s many architectural elements.

      Jamstack, Varty said, plays mind games with us to make it hard to know, especially when first getting acquainted, to know where a given snippet of code will actually be executed.

      Tessa Mero’s walkthrough of the Cloudinary (where she is a developer advocate) options for media accessibility was interesting, in that Cloudinary does indeed do some interesting tricks like using AI to automatically generate ALT tag text for images, checking photos for potential problems when viewed by color-blind users, and providing machine-generated captioning for videos. She also pointed to several open resources for testing accessibility issues.

      Ohad Eder-Pressman

      Ohad Eder-Pressman, cofounder and ceo of Stackbit, presented two open tools that Stackbit has created for spinning up various flavors of jamstack site. A site called Jamstack.new let’s you pick a theme, a static-site generator, and a headless store for content, then creates an instance nearly instantaneously. The company also maintains jamstackthemes.dev, which is a repository for, you guessed it, themes that can be used with various frameworks.

    2. TheJam.dev 2021 kicks off with azure and ecommerce

      Today was the first day of a two-day Jam.Dev event online. The event had a lot to offer people who are presently trying to sort out the lay of the land in the static site generator ecosystem.

      The Azure Take on Static

      Shmuela Jacobs, cloud developer advocate at Microsoft, walked through the Static Web App service that is currently in developer preview on the Azure platform. The introduction of the service makes perfect sense, of course, given the success of companies like Netlify and Vercel in providing production build and hosting services. The basic structure of the new service looks a lot like Netlify in terms of what it does, but doesn’t have nearly as friendly a UI, at least not at this point. Part of this no doubt lies in the higher degree of complexity that large sites on Azure tend to bring to their cloud game.

      Like other options in the space, Azure basis the static service on repositories stored in github, such that when a new commit is made to the application’s repository, Azure runs the build and, assuming a successful build, deploys the application to the Azure CDN. You set up a config file that sets up things like environment variables that your app needs in the production environment.

      Shmuela Jacobs, cloud developer advocate at Microsoft

      By and large, this look at Azure’s entry into the jamstack ecosystem (beyond the already existent capability to host Docker images of jamstack servers) was perhaps the most interesting part of the day.

      Stephanie Eckles, a software engineer at Microsoft, gave a full-throated and interesting walkthrough of the 11ty static site generator. She built a basic site as a demo that ran in 3 minutes, complete with a timer running in the screen. It definitely underscored the simplicity and direct approach of 11ty compared to static sites built with React or Vue frameworks running on client pages. A panel that followed brought together Sara Drasner, vp of developer experience at Netlify, Phil Hawksworth, developer experience engineer at Netlify, and Gift Egwuenu, frontend developer at Passionate People. These are all heavy hitters in the jamstack world, but the panel never quite gelled and thus wandered a bit.

      Quicktime

      A series of quick, ten-minute talks covered a lot of ground, including an overview of Google’s Lightspeed metrics given by freelance developer Henri Helvetica. There’s no doubt that Helvetica knows whereof he speaks—he’s a frequent speaker at events and turns up involved in lots of projects—but the lightning format didn’t serve him well when it comes to Google metrics, which get deep and detailed in a hurry.

      Tamas Piros, developer advocate at Cloudinary, talked about image management (and, in particular, distributing tailored images from the edges of the net. The takeaway here was a link to a site he put together for comparing various approaches in real time. It’s at know-your-media.dev. Miriam Schwab, CEO and cofounder of Strattic, talked through the basic scenarios for making WordPress a backend for various kinds of static site, as well as making a compelling argument for why this is important in a world that has become very accustomed to WordPress and capable of using it to turn out tailored sites very quickly.

      Miriam Schwab, CEO and cofounder of Strattic

      The final two talks of the day focused on jamstack approaches to ecommerce, though largely it was a matter of showing that it was indeed possible to do. Flor Antara of Zipwhip worked through four approaches to selling on static-based sites.

      Option one, Antara said, was the non-jamstack Shopify-like third-party service. This part of the talk had me looking for the option to turn the playback speed to 1.5x. This can be a problem with live events. Option two was integration with an API, which she pointed out could be fairly time consuming to set up. Option 3 was what Antara called “Add-on” ecommerce.

      Snipcart, etc

      In a quick demo, she demonstrated the Square “Buy Link”, the second the PayPal equivalent, the third was Shopify buy button, and the final was SnipCart, which is, not to split hairs, actually an API approach, just one that happens to use GraphQL. These are all good ways to handle basic sales capabilities, but somewhat glossed over in the presentation was the fact that if you go with, say, a PayPal buy button, then you have to handle anything that would typically fall into tasks that collectively we call a shopping cart. In other words, you have to have static pages that describe the products. You don’t get any integration with inventory data unless you code it yourself. If you want to offer, say, three for the price of two bundling, you’ve got to track how many things have been ordered and whether the relevant items quality for the discount.

      It _is_ possible to support some shopping cart options into a PayPal scenario, but basically you are handing off to PayPal, just like you might hand off to any other third-party ecommerce store, as per Antara’s Option One. But SnipCart is a different animal in that it supports GraphQL. As a technicality, this is an API interface, too, but it’s particularly well geared to jamstack frameworks that use GraphQL. Antara gave a walkthrough of how this could be added to her flat HTML product pages, but arguably what’s valuable here is the ability to use templated product pages that query SnipCart for data elements that are dropped into the page.

      The conclusion of the talk, that SnipCart is the clean, jam-savvy way to do this, is spot on. Since this was a demo-based talk, SnipCart was the only vendor discussed as a headless eCommerce vendor, but needless to say, there are others, such as commercetools, and even a headless variant of Shopify.

      We’ll cover day two of Jam.Dev in a separate article.