Spam Detection APIs

I was trying to research the landscape of these the other day — And by research, I mean light Googling and asking on Twitter. Weirdly, very little comes to mind when thinking about spam detection APIs. I mean some kind of URL endpoint, paid or not, where you can hit it with a block of text and whatever metadata it wants and it’ll tell you if it’s spam or not. Seems like something an absolute buttload of the internet could use and something companies of any size could monetize or offer free to show off their smart computer machines.

Akismet is the big kid on the block.

You might think of Akismet as a WordPress thing, and it is. It’s an Automattic product and is perhaps primarily used as a WordPress plugin. I run that here on CSS-Tricks and it’s blocked 1,989,326 so far.

It also has a generic API. There are libraries for Dart, JavaScript, PHP, Python, Ruby, Go, etc, as well as plugins for other CMSs. So if you use a different CMS or have your custom app, you can still use Akismet for spam detection.

After you get an API key, you can POST to a URL endpoint with all the data it needs and it’ll respond true if it’s spam or false if it’s not.

To get better results over time, you can also submit content telling it if it’s spam or ham (ham is the opposite of spam… good content).


Several folks mentioned Plino to me.

There is a lot to like here, like the fact that it’s free and returns a JSON response like you might be used to in development. There is the fancy buzzword “Machine Learning” being used here, too. It makes me think that with lots of people using this, it’ll get smarter and smarter as it goes. But there is no way to submit ham/spam, so I’m not sure that’s really the case.

There is other stuff that makes me nervous. It’s clearly on Heroku which is kinda expensive at scale, and so with no pricing model it seems like it could go away anytime. Sorta feels like a fun-but-abandoned side project. Last commit was two years ago, as I write.


OOPSpam looks super similar to Plino, but has a pricing model, which is nice. They publish their latency, which is over two seconds. I haven’t compared that to the others so I have no idea if they are all that slow. Two seconds seems like a lot for an API call to me, but maybe it’s not that big of a deal since it’s an async submit?


CleanTalk has a clear pricing structure and appears to have plenty of customers, which is a plus to me. The website looks a little janky though, which makes me worry a little.

(Sorry if that’s a little rude, but it’s just mental math to me. Good design is one of the least expensive investments a company can make to increase trust, so companies that overlook it make me wonder.)

It looks like they have a variety of anti-spam solutions though, which is interesting. For example, you can ask an API to see if an IP, email, or domain is on a blacklist, which is a pretty raw way of blocking bad stuff, but useful for stuff like protecting against spam registrations (rather than just checking blocks of text). They also have a firewall solution, which is interesting for folks trying to block spam before it even touches their servers.

Email options…

There are a couple out there that seem rather specific to testing emails. As in, testing your own emails before you send them to make sure they aren’t considered spam by email services. Here are a couple I cam across while looking around:

The post Spam Detection APIs appeared first on CSS-Tricks.

The Case For Brand Systems: Aligning Teams Around A Common Story

The Case For Brand Systems: Aligning Teams Around A Common Story

The Case For Brand Systems: Aligning Teams Around A Common Story

Laura Busche

There’s a disconnect. If you’ve been in business for enough time you’ve definitely felt it. Teams are pulling companies in different directions with internal processes and specialized frameworks for absolutely everything. They’re focused on building their “part” of the product, and doing it incredibly well. There’s just one problem: our internal divisions mean nothing to customers.

In customers’ eyes, it’s the same brand replying to their support tickets and explaining something in a modal; the same entity is behind the quality of the product they use and the ads that led them to that product in the first place. To them, there are no compartments, no org charts, no project managers. There is only one brand experience. At the end of the day, customers are not tasting individual ingredients, or grabbing a bite during each stage of preparation, they’re eating the entire meal. At once. In sit-downs that keep getting shorter.

Something is getting lost in the process. Somewhere between our obsession with specializing and our desire to excel at individual roles, we’ve lost perspective of the entire brand experience. We spend our days polishing individual touchpoints, but not enough time zooming out to understand how they come together to shape our customer’s journey. The time for shying away from the word “holistic” is up — it’s the only way customers will ever perceive you. And that is the ultimate inspiration behind Brand Systems, a tool we will explore throughout this article.

What Is A Brand System?

At its core, a Brand System is a shared library that helps define, preserve, and improve the customer’s experience with the brand.

Just like we can’t assume that the sum of quality ingredients will result in a great meal, our individual contributions won’t magically translate into a memorable brand experience for customers. Their brand experiences are blended, multifaceted, and owner-blind. It’s time for the product, design, engineering, marketing, support, and various other functions to establish a single source of truth about the brand that is accessible to, understood, and used by all. That source is a Brand System.

Why Is It Useful? The Benefits Of Building A Brand System

Your brand is the story that customers recall when they think about you. When you document that story, your team can align to live up to and protect those standards consistently. There are multiple benefits to building and maintaining a Brand System:

  • Cohesion
    It helps preserve a uniform presence for the brand.
  • Access
    It empowers teams to apply assets consistently. A common language facilitates collaboration across different functional areas.
  • Flexibility
    This system is in continuous iteration, providing an up-to-date source of truth for the team.
  • Speed
    When your building blocks are readily available, everything is easier to construct. Collaboration is also accelerated as individuals get a fundamental understanding of how others’ work contributes to the brand experience.
  • Ethos
    Documenting the brand’s ethos will motivate the team to preserve, protect, and extend it. That level of care is perceived and appreciated by users.

To accomplish the above most effectively, the Brand System must remain accessible, empowering, holistic, extensible, flexible, and iterative. Let’s take a closer look at each of these traits and some examples of how they can be put in practice.


Open to all team members, regardless of their level of technical expertise or direct involvement with each element. Systems that perpetuate divisions within organizations can be visually mesmerizing, but end up fragmenting the brand experience.

Help Scout provides a visual example of what the concepts of illustration scale and grid mean for those who may not be familiar with them. (Large preview)


Full of examples that encourage continuous application. Some aspects of the brand experience can be hard to grasp for those who don’t interact with them daily, but a Brand System should empower everyone to recognize what is fundamentally on and off-brand — regardless of the touchpoint involved. Does the company’s support team feel confident about how the brand is visually represented? Does the design team have a general idea of how the brand responds to customers’ requests?

Webflow provides clear examples and instructions to empower different team members to write for the product, even if they’re not used to it. (Large preview)


No aspect of the brand’s execution is too foreign to include. Brand Systems surface the tools and frameworks various teams are using to clarify the bigger picture. Too often the customer’s experience appears disjointed because we’ve compartmentalized it. The brand experience “belongs” to marketing, or design, or some kind of executive-level team, so resources like UI components or support scripts are dealt with separately. As the unifying backbone of all business functions, the brand experience informs execution at every level.

For WeWork, physical spaces are a key part of the entire experience. Their brand system includes guidelines in this respect. (Large preview)


Individual teams can develop specific subsections within the system to fit their needs. Regardless of how specialized these different areas get, the Brand System remains accessible to all. Team members decide how deeply they want to dive into each element, but the information is readily available.

Atlassian makes use of its Confluence platform to host guidelines related to different parts of the brand experience. Sections have varying levels of access and are regularly maintained by different teams. (Large preview)


There can be alternative versions of the Brand System for external audiences, including media and partners. While we’d like the brand experience to unfold in owned channels, the reality is that sometimes customers interact with it through earned channels controlled by third parties. In those cases, a minimized version of the Brand System can help preserve the story, voice, and visual style.

Instagram, for example, offers a special set of guidelines for users broadcasting content about the brand. (Large preview)


The Brand System should evolve and be continuously updated over time. To that end, host and serve the content in a way that makes it easy to access and edit as things change.

Salesforce surfaces ongoing updates to its Lightning system in a section called Release Notes. (Large preview)

What Does A Brand System Contain?

Brand Systems solve a fundamental disconnect in teams. Nobody outside of marketing feels empowered to market the product, nobody outside of design feels like they have a solid grasp of the brand’s style guidelines, nobody outside of support feels confident responding to a customer. Sounds familiar? That’s why it’s crucial to build a Brand System that is as all-encompassing and transparent as possible.

While Design Systems are the closest implementation of a resource like this, a Brand System is centered around the brand story, understanding symbols and strategy as necessary layers in its communication. It is informed by product and design teams, but also functional areas like support, marketing, and executive leadership that are key to shaping the entire brand experience. In Brand Systems, visual components are presented in the context of a business model, a company mission, positioning, and other strategic guidelines that must be equally internalized by the team.

Comet, a Design System by Discovery Education. (Large preview)

A Brand Style Guide is another commonly used tool to align teams around a set of principles. While useful, these guides focus heavily on marketing and design specifications. Their main objective is to impart a shared visual language for the brand so that it is applied cohesively across the board. That resolves part of the problem but doesn’t reveal how other functional areas contribute to the overall brand experience. Therefore, these guidelines could be considered as part of the larger Brand System.

Brand Guidelines for the Wildlife Conservation Society
Brand Guidelines for the Wildlife Conservation Society (Designed by Pentagram) (Large preview)

That said, these are some of the sections and components you should consider including in your Brand System:


If the brand experience is embroidery, the story is the thread weaving all the touchpoints together. It reveals what has been and will continue to be important, who the brand is trying to serve, and how it plans to do so most effectively. Start your Brand System by answering questions like:

  • What is this brand’s core value proposition?
  • What does its history look like? Include a timeline and key milestones.
  • How do you summarize both of the above in an “About Us” blurb?
  • What are the brand’s core values? What propels this team forward?
  • Who is the audience? Who are the main personas being addressed and what are these individuals trying to get done?
(Large preview)
The Smithsonian Institution included a section called Audience Segments in the strategy section of their branding website. (Large preview)
  • What does their journey with us look like? If known, what is their sentiment towards the brand?
  • What is the brand’s mission as it relates to its target customers? How about the team itself and society at large?
  • How does this business model work, in general terms? (Specifics will be included in the “Strategy” section).
  • Who are the brand’s direct competitors? What sets it apart from them?
  • How does this brand define product/service quality? Are there any values around that?
  • What is the brand’s ultimate vision?
Shopify summarizes the brand’s Product Experience Principles in their Polaris design system. (Large preview)


You know what drives the brand and the narrative it brings to the table. This part of the Brand System is about actually representing that. Symbols are sensory: they define what the brand looks, sounds, and feels like. Because they help us convey the story across multiple touchpoints, it’s vital for the entire team to have a grasp of what they stand for and how they can be properly deployed.

Here are some examples of building blocks you’ll want to define in this section:

  • Main and alternative versions of the brand’s logo
  • Color palette
  • Typography scheme
  • Icons, photography, and illustration style
  • Patterns, lines, and textures
  • Layout and spacing
  • Slide deck styling
  • Stationery and merchandising applications
  • Motion & sound, including audiobranding
  • Packaging (if applicable)
  • Scent (if applicable).

For brands built around digital products:

  • User Interface components
  • Interaction patterns
  • Key user views & states
  • User Experience guidelines
  • Code standards
  • Tech stack overview.
IBM includes patterns for common actions like “Next” in its Carbon design system. (Large preview)

Bear in mind that the nature of your product will determine how you complete the section above. A tech-based company might list elements like interaction patterns, but a retail brand might look at aspects like store layout.


Once you’ve clarified the brand’s story, and the symbols that will represent it, define how you go about growing it. This part of the Brand System addresses both messaging and method, narrative and tactics.

It’s not enough for the team to be aware of why this brand is being built: the goal is to get everyone familiar with how it is sustained, grown, and communicated.

Just like customer support can feel alienated from the design function, these growth-related tenets are often not surfaced beyond marketing, acquisition, or executive conversations. However, those kinds of strategic ideas do impact customers at every touchpoint. A Brand System is a crash course that makes high-level perspective accessible to all, unlocking innovation across the entire team.

Here are some guiding questions and components to include:

  • How does this brand define success? What growth metric does the team focus on to track performance? (GMV, revenue, EBITDA, sales, etc).
  • What does the conversion funnel look like? How does this brand acquire, activate and retain customers?
    • What is the average Customer Acquisition Cost (CAC)?
    • What is the retention rate?
    • What is the Customer’s Lifetime Value (LTV)?
    • Which channels drive the most revenue? Traffic?
    • Which products and categories drive the most revenue? Traffic?
    • Which of the buyer personas defined in the “Story” section bring the most revenue? Traffic?
  • What are the brand’s key objectives for this year (to be updated)? These are company-wide goals.
  • What initiatives or themes is the team focusing on to meet those objectives this year?
  • How is the team organized to meet those objectives?
  • What channels does this brand use to communicate with its target audience? Name them and specify how big they are in terms of reach and/or traffic.
    • Owned
      • Website, blog, or other web properties
      • Social channels
      • Email
    • Earned
      • Ongoing brand partnerships
      • Referrals
    • Paid
      • Specific ad platforms
      • Influencers
      • Affiliates
  • What is this brand’s personality like?
  • What defines the brand’s voice? How does it adopt different tones in specific situations?
  • How does the brand’s voice come to life in owned, earned, and paid channels?
    • Company website and landing pages
    • Social channels. Clarify if tone varies
    • Email
    • Ads
    • Sales collateral
    • Press releases
    • Careers page & job sites
  • How does the brand’s voice come to life in the customer’s experience with the product, before, during, and after purchase?
    • Call to action
    • Navigation
    • Promotion
    • Education
    • Success/error
    • Apology/regret
    • Reassurance/support
  • How does the brand’s voice come to life internally (within the team)?
    • Employee handbooks
    • Onboarding process.
  • What topics should this brand aim to be a thought leader at?
UC Berkeley defines the themes and key messages to highlight when speaking to different audiences. (Large preview)
  • Grammar and spelling-wise, does this brand adhere to a specific style manual?
  • What are some common words and expressions users can expect from this brand?
Mailchimp’s Content Style Guide
Mailchimp’s Content Style Guide (Source) (Large preview)

How To Get Started With Your Own Brand System

If you’re feeling ready to shape your own Brand System, here are some steps you can take to approach the challenge as a team:

1. Kickoff

Set up a company-wide planning session. If you can’t have everyone attend, make sure there’s someone representing product, design, marketing, support, and the executive team. Lead a conversation with two goals:

  • Brand audit
    How is the brand represented in various contexts? Is there brand debt to account for? Consider the brand’s story, symbols, and strategy.
  • Brand definition
    Discuss how this brand:
    • sounds,
    • looks,
    • speaks,
    • feels,
    • interacts,
    • introduces itself in a few words.

2. Production

After having that open discussion, delegate the various sections described above (Story, Symbols, Strategy) to the teams that interact most closely with each of them. Ask specific individuals to document the brand’s point of view regarding each system component (listed in point 2).

3. Publication

Upload the full Brand System to a central location where it is readily available and editable. Schedule a team-wide presentation to get everyone on the same page.

4. Summary

Condense the main guidelines in a one-page document called Brand-At-a-Glance. Here are some of the key points you could include:

  • Brand mission, vision, and values
  • Visual identity: color palette, main logo versions, type scheme, illustration style
  • About Us blurb.

5. Revision

Establish a periodic cross-functional meeting where the brand is protected and defined. Frequency is up to you and your team. This is also where the Brand System is formally updated, if needed. In my experience, unless this space is scheduled, the revisions simply won’t happen. Time will pass, customers’ needs will change, the brand experience will shift, and there won’t be a common space to document and discuss it all.

Brand Systems: Aligning Teams Around A Common Story

When customers interact with your brand, they’re not aware of what’s going on backstage. And there is no reason they should. All they perceive is the play you’re presenting, the story you’re sharing, and the solution it represents for them. When the individual actors go off script, as great as they might sound solo, the brand experience breaks.

Enter the Brand System: a shared library that defines the brand’s story, symbols, and strategy. In doing so, this tool aligns all actors around the multi-faceted experience customers truly perceive. Within teams, Brand Systems help avoid fragmentation, confusion, and exclusion. Externally, they’re a script to deliver the most compelling brand experience possible — at every touchpoint, every single time.

Smashing Editorial (ah, yk, il)
What I Learned From Designing AR Apps

What I Learned From Designing AR Apps

What I Learned From Designing AR Apps

Gleb Kuznetsov

The digital and technological landscape is constantly changing — new products and technologies are popping up every day. Designers have to keep track of what is trending and where creative opportunities are. A great designer has the vision to analyze new technology, identify its potential, and use it to design better products or services.

Among the various technologies that we have today, there’s one that gets a lot of attention: Augmented Reality. Companies like Apple and Google realize the potential of AR and invest significant amounts of resources into this technology. But when it comes to creating an AR experience, many designers find themselves in unfamiliar territory. Does AR require a different kind of UX and design process?

As for me, I’m a big fan of learning-by-doing, and I was lucky enough to work on the Airbus mobile app as well as the Rokid AR glasses OS product design. I’ve established a few practical rules that will help designers to get started creating compelling AR experiences. The rules work both for mobile augmented reality (MAR) and AR glasses experiences.

Rokid Glasses motion design exploration by Gleb Kuznetsov


Let’s quickly define the key terms that we will use in the article:

  • Mobile Augmented Reality (MAR) is delivering augmented reality experienced on mobile devices (smartphones and tablets);
  • AR Glasses are a wearable smart display with a see-through viewing an augmented reality experience.

1. Get Buy-In From Stakeholders

Similar to any other project you work for, it is vital that you get support from stakeholders as early in the process as is possible. Despite being buzzed about for years, many stakeholders have never used AR products. As a result, they can question the technology just because they don’t understand the value it delivers. Our objective is to get an agreement from them.

“Why do we want to use AR? What problem does it solve?” are questions that stakeholders ask when they evaluate the design. It’s vital to connect your design decisions to the goals and objectives of the business. Before reaching stakeholders, you need to evaluate your product for AR potential. Here are three areas where AR can bring a lot of value:

  • Business Goals
    Understand the business goals you’re trying to solve for using AR. Stakeholders always appreciate connecting design solutions to the goals of the business. A lot of time business will respond to quantifiable numbers. Thus, be ready to provide an explanation off how your design is intended to help the company make more money or save more money.
  • Helpfulness For Users
    AR will provide a better user experience and make the user journey a lot easier. Stakeholders appreciate technologies that improve the main use of the app. Think about the specific value that AR brings to users.
  • Creativity
    AR is excellent when it comes to creating a more memorable experience and improving the design language of a product. Businesses often have a specific image they are trying to portrait, and product design has to reflect this.

Only when you have a clear answer to the question “Why is this better with AR?”, you will need to share your thoughts with stakeholders. Invest your time in preparing a presentation. Seeing is believing, and you’ll have better chances of buy-in from management when you show a demo for them. The demo should make it clear what are you proposing.

2. Discovery And Ideation

Explore And Use Solutions From Other Fields

No matter what product you design, you have to spend enough time researching the subject. When it comes to designing for AR, look for innovations and successful examples with similar solutions from other industries. For example, when my team was designing audio output for AR glasses, we learned a lot from headphones and speakers on mobile phones.

Design User Journey Using “As A User I Want” Technique

One of the fundamental things you should remember when designing AR experiences is that AR exists outside of the phone or glasses. AR technology is just a medium that people use to receive information. The tasks that users want to accomplish using this technology are what is really important.

“How to define a key feature set and be sure it will be valuable for our users?” is a crucial question you need to answer before designing your product. Since the core idea of user-centered design is to keep the user in the center, your design must be based on the understanding of users, their goals and contexts of use. In other words, we need to embrace the user journey.

When I work on a new project, I use a simple technique “As a ||, I want [goal] because [reason].” I put myself in the user’s shoes and think about what will be valuable for them. This technique is handy during brainstorming sessions. Used together with storyboarding, it allows you to explore various scenarios of interaction.

In the article “Designing Tomorrow Today: the Airbus iflyA380 App,” I’ve described in detail the process that my team followed when we created the app. The critical element of the design process was getting into the passenger’s mind, looking for insights into what the best user experience would be before, during and after their flight.

To understand what travelers like and dislike about the travel experience, we held a lot of brainstorming sessions together with Airbus. Those sessions revealed a lot of valuable insights. For example, we found that visiting the cabin (from home) before flying on the A380 was one of the common things users want to do. The app uses augmented reality so people can explore the cabin and virtually visit the upper deck, the cockpit, the lounges — wherever they want to go — even before boarding the plane.

IFLY A380 iOS app design by Gleb Kuznetsov
IFLY A380 iOS app design by Gleb Kuznetsov. (Large preview)

App also accompanies passengers from the beginning to the end of their journey — basically, everything a traveler wants to do with the trip is wrapped up in a single app. Finding your seat is one of the features we implemented. This feature uses AR to show your seat in a plane. As a frequent traveler, I love that feature; you don’t need to search for the place at the time when you enter the cabin, you can do it beforehand — from the comfort of your couch. Users can access this feature right from the boarding pass — by tapping on ‘glass’ icon.

IFLY A380 app users can access the AR feature by tapping on the ‘glass’ icon
IFLY A380 app users can access the AR feature by tapping on the ‘glass’ icon. (Large preview)

Narrow Down Use Cases

It might be tempting to use AR to solve a few different problems for users. But in many cases, it’s better to resist this temptation. Why? Because by adding too many features in your product, you make it not only more complex but also more expensive. This rule is even more critical for AR experience that generally requires more effort. It’s always better to start with simple but well-designed AR experience rather than multiple complex but loose designed AR experiences.

Here are two simple rules to follow:

  • Prioritize the problems and focus on the critical ones.
  • Use storyboarding to understand exactly how users will interact with your app.
  • Remember to be realistic. Being realistic means that you need to strike a balance between creativity and technical capabilities.

Use Prototypes To Assess Ideas

When we design traditional apps, we often use static sketches to assess ideas. But this approach won’t work for AR apps.

Understanding whether a particular idea is good or bad cannot be captured from a static sketch; quite often the ideas that look great on paper don’t work in a real-life context.

Thus, we need to interact with a prototype to get this understanding. That’s why it’s essential to get to prototyping state as soon as possible.

It’s important to mention that when I say ‘prototyping state’ I don’t mean a state when you create a polished high-fidelity prototype of your product that looks and work as a real product. What I mean is using a technique of rapid prototyping and building a prototype that helps you experience the interaction. You need to make prototypes really fast — remember that the goal of rapid prototyping is in evaluating your ideas, not in demonstrating your skills as a visual designer.

3. Design

Similar to any other product you design, when you work on AR product, your ultimate goal is to create intuitive, engaging, and clean interface. But it can be challenging since the interface in AR apps accounts both for input and output.

Physical Environment

AR is inherently an environmental medium. That’s why the first step in designing AR experience is defining where the user will be using your app. It’s vital to select the environment up front. And when I say ‘environment’, I mean a physical environment where the user will experience the app — it could be indoors or outdoors.

Here are three crucial moments that you should consider:

  1. How much space users need to experience AR? Users should have a clear understanding of the amount of space they’ll need for your app. Help users understand the ideal conditions for using the app before they start the experience.
  2. Anticipate that people will use your app in environments that aren’t optimal for AR. Most physical environments can have limitations. For example, your app is AR table tennis game but your users might not have a large horizontal surface. In this case, you might want to use a virtual table generated based on your device orientation.
  3. Light estimation is essential. Your app should analyze the environment automatically and provide contextual guidance if the environment is not good enough. If the environment is too dark or too bright for your app, tell the user that they should find a better place to use your app. ARCore and ARKit have a built-in system for light estimation.

When my team designed Airbus i380 mobile AR experience, we took the available physical space into account. Also, we’ve considered the other aspects of interaction, such as the speed at which the user should make decisions. For instance, the user who wants to find her seat during the boarding won’t have too much time.

We sketched the environment (in our case, it was a plane inside and outside) and put AR objects in our sketch. By making our ideas tangible, we got an understanding of how the user will want to interact with our app and how our app will adapt to the constraints of the environment.

AR Realism And AR Objects Aesthetics

After you define the environment and required properties, you will need to design AR objects. One of the goals behind creating AR experience is to blend virtual with real. The objects you design should fit into the environment — people should believe that AR objects are real. That’s why it’s important to render digital content in context with the highest levels of realism.

Here are a few rules to follow:

  • Focus on the level of details and design 3D assets with lifelike textures. I recommend using multi-layer texture model such as PBR (Physically Based Rendering model). Most AR development tools support it, and this is the most cost-effective solution to achieve an advanced degree of detail for your AR objects.
  • Get the lighting right. Lighting is a very crucial factor for creating realism — the wrong light instantly breaks the immersion. Use dynamic lighting, reflect environmental lighting conditions on virtual objects, cast object shadows, and reflections on real-world surfaces to create more realistic objects. Also, your app should react to real-world changing of lighting.
  • Minimize the size of textures. Mobile devices are generally less powerful than desktops. Thus, to let your scene load faster, don’t make textures too large. Strive to use 2k resolution at most.
  • Add visual noise to AR textures. Flat-colored surfaces will look fake to the user’s eye. Textures will appear more lifelike when you introduce rips, pattern disruptions, and other forms of visual noise.
  • Prevent flickering. Update the scene 60 times per second to prevent flickering of AR objects.

Design For Safety And Comfort

AR usually accompanied by the word ‘immersive.’ Creating immersive experience is a great goal, but AR immersion can be dangerous — people can be so immersed in smartphones/glasses, so they forget what is happening around them, and this can cause problems. Users might not notice hazards around them and bump into objects. This phenomenon is known as cognitive tunneling. And it caused a lot of physical traumas.

  • Avoid users from doing anything uncomfortable — for example, physically demanding actions or rapid/expansive motion.
  • Keep the user safe. Avoid situations when users have to walk backward.
  • Avoid long play AR sessions. Users can get fatigued using AR for extended periods. Design stop points and in-app notifications that they should take a break. For instance, if you design an AR game, let users pause or save their progress.

Placement For Virtual Objects

There are two ways of placing virtual objects — on the screen or in the world. Depending on the needs of your project and device capabilities, you can follow either the first or second approach. Generally, virtual elements should be placed in world space if they suppose to act like real objects (e.g., a virtual statue in AR space), and should be placed as an on-screen overlay if they intended to be UI controls or information messages (e.g., notification).

Rokid Glasses
Rokid Glasses. (Large preview)

‘Should every object in AR space be 3D?’ is a common question among designers who work on AR experiences. The answer is no. Not everything in the AR space should be 3D. In fact, in some cases like in-app notifications, it’s preferable to use flat 2D objects because they will be less visually distracting.

Rokid Glasses motion design exploration by Gleb Kuznetsov
Rokid Glasses motion design exploration by Gleb Kuznetsov. (Large preview)

Avoid Using Haptic Feedback

Phone vibrations are frequently used to send feedback in mobile apps. But using the same approach in AR can cause a lot of problems — haptic feedback introduces extra noise and makes the experience less enjoyable (especially for AR Glasses users). In most cases, it’s better to use sound effect for feedback.

Make A Clear Transition Into AR

Both for MAR and AR glass experiences, you should let users know they’re about to transition into AR. Design a transition state. For the ifly380 app, we used an animated transition — a simple animated effect that user sees when taps on the AR mode icon.

Trim all the fat.

Devote as much of the screen as possible to viewing the physical world and your app’s virtual objects:

  • Reduce the total number of interactable elements on the screen available for the user at one moment of time.
  • Avoid placing visible UI controls and text messages in your viewport unless they are necessary for the interaction. A visually clean UI lends itself seamlessly to the immersive experience you’re building.
  • Prevent distractions. Limit the number of times when objects appear on the user screen out of the blue. Anything that appears out of the blue instantly kills realism and make the user focus on the object.

AR Object Manipulation And Delineating Boundaries Between The ‘Augment’ And The ‘Reality’

When it comes to designing a mechanism of interaction with virtual objects, favor direct manipulation for virtual objects — the user should be able to touch an object on the screen and interact with it using standard, familiar gestures, rather than interact with separate visible UI controls.

Also, users should have a clear understanding of what elements they can interact with and what elements are static. Make it easy for users to spot interactive objects and then interact with them by providing visual signifiers for interactive objects. Use glowing outlines or other visual highlights to let users know what’s interactive.

Scan object effect for outdoor MAR by Gleb Kuznetsov
Scan object effect for outdoor MAR by Gleb Kuznetsov. (Large preview)

When the user interacts with an object, you need to communicate that the object is selected visually. Design a selection state — use either highlight the entire object or space underneath it to give the user a clear indication that it’s selected.

Last but not least, follows the rules of physics for objects. Just like real objects, AR objects should react to the real-world environment.

Design For Freedom Of Camera

AR invites movement and motion from the user. One of the significant challenges when designing or AR is giving users the ability to control the camera. When you give users the ability to control the view, they will swing device around in an attempt to find the points of interest. And not all apps are designed to help the user to control the viewfinder.

Google identifies four different ways that a user can move in AR space:

  1. Seated, with hands fixed.
  2. Seated, with hands moving.
  3. Standing still, with hands fixed.
  4. Moving around in a real-world space.

The first three ways are common for mobile AR while the last one is common for AR glasses.

In some cases, MAR users want to rotate the device for ease of use. Don’t interrupt the camera with rotation animation.

Consider Accessibility When Designing AR

As with any other product we design, our goal is to make augmented reality technology accessible for people. Here are a few general recommendations on how to address real-world accessibility issues:

  • Blind users. Visual information is not accessible to blind users. To make AR accessible for blind users, you might want to use audio or haptic feedback to deliver navigation instructions and other important information.
  • Deaf or hard-hearing users. For AR experience that requires voice interaction, you can use visual signals as an input method (also known as speechreading). The app can learn to analyze lip movement and translate this data in commands.

If you’re interested in learning more practical tips on how to create accessible AR apps, consider watching the video talk by Leah Findlater:

Encourage Users To Move

If your experience demands exploration, remind users they can move around. Many users have never experienced a 360-degree virtual environment before, and you need to motivate them to change the position of their device. You can use an interactive object to do that. For example, during I/0 2018, Google used an animated fox for Google Maps that guided users to the target destination.

This AR experience uses an animated bird to guide users
This AR experience uses an animated bird to guide users. (Large preview)

Remember That Animation Is A Designer’s Best Friend

Animation can be multipurpose. First, you can use a combination of visual cues and animation to teach users. For example, the animation of a moving phone around will make it clear what users have to do to initialize the app.

Second, you can use animation to create emotions.

One second of emotion can change the whole reality for people engaging with a product.

Well-designed animated effects help to create a connection between the user and the product — they make the object feel tangible. Even a simple object such as loading indicator can build a bridge of trust between users and the device.

Rokid Alien motion design by Gleb Kuznetsov
Rokid Alien motion design by Gleb Kuznetsov. (Large preview)

A critical moment about animation — after discovering the elements of design and finding design solutions for the animation base, it’s essential to spend enough time on creating a proper animated effect. It took lots of iterations to finish a loading animation that you see above. You have to test every animation to be sure it works for your design and be ready to adjust color, positioning, etc. to give the best effect.

Prototype On The Actual Device

In the interview for Rokid team, Jeshua Nanthakumar mentioned that the most effective AR prototypes are always physical. That’s because when you prototype on the actual device, from the beginning, you make design work well on hardware and software that people actually use. When it comes to unique displays like on the Rokid Glasses, this methodology is especially important. By doing that you’ll ensure your design is implementable.

Motion design language exploration for AR Glasses Rokid by Gleb Kuznetsov
Motion design language exploration for AR Glasses Rokid by Gleb Kuznetsov. (Large preview)

My team was responsible for designing the AR motion design language and loading animation for AR glasses. We decided to use a 3D sphere that will be rotated during the loading and will have nice reflections on its edges. The design of the animated effect took two weeks of hard work of motion designers and it looked gorgeous on high-res monitors of our design team, but the final result wasn’t good enough because the animation caused motion sickness.

Motion sickness often caused by the discrepancies between the motion perceived from the screen of AR Glasses and the actual movement of the user’s head. But in our case, the root cause of the motion sickness was different — since we put a lot of attention in polishing details like shapes, reflections, etc. unintentionally we made users focus on those details while the sphere was moving.

As a result, the motion happened in the periphery, and since humans are more sensitive to the moving objects in the periphery this caused motion sickness. We solved this problem by simplifying the animation. But it’s critical to mention that we won’t be able to find this problem without testing on the actual device.

If we compare the actual procedure of testing of AR apps with traditional GUI apps, it will be evident that testing AR apps require more manual interactions. A person who conducts testing should determine whether the app provides the correct output based on the current context.

Here are a few tips that I have for conducting efficient usability testing sessions:

  • Prepare a physical environment to test in. Try to create real-world conditions for your app — test it with various physical objects, in different scenes with different lighting. But the environment might not be limited to scene and lighting.
  • Don’t try to test everything all at once. Use a technique of chunking. Breaking down a complex flow into smaller pieces and testing them separately is always beneficial.
  • Always record your testing session. Record everything that you see in the AR glass. A session record will be beneficial during discussions with your team.
  • Testing for motion sickness.
  • Share your testing results with developers. Try to mitigate the gap between design and development. Make sure your engineering team knows what problem you face.


Similar to any other new technology, AR comes with many unknowns. Designers who work on AR projects have a role of explorers — they experiment and try various approaches in order to find the one that works best for their product and delivers the value for people who will use it.

Personally, I believe that it’s always great to explore new mediums and find new original ways of solving old problems. We are still at the beginning stages of the new technological revolution — the exciting time when technologies like AR will be an expected part of our daily routines — and it’s our opportunity to create a solid foundation for the future generation of designers.

Smashing Editorial (cc, yk, il)
Popular Design News of the Week: June 17, 2019 – June 23, 2019

Every week users submit a lot of interesting stuff on our sister site Webdesigner News, highlighting great content from around the web that can be of interest to web designers. 

The best way to keep track of all the great stories and news being posted is simply to check out the Webdesigner News site, however, in case you missed some here’s a quick and useful compilation of the most popular designer news that we curated from the past week.

Note that this is only a very small selection of the links that were posted, so don’t miss out and subscribe to our newsletter and follow the site daily for all the news.

Internet has Meltdown Over Facebook’s Libra Logo


How to Section your HTML


Clarity 2.0 Released – Open Source Design System


Facebook Libra


One Designer’s Struggle to Redesign his Website


Building a Web-Based Motion Graphics Editor


Styling in Modern Web Apps


7 Ways to Design Better Forms


Why I Don’t Use Web Components


Birds’ Eye Logos


Introducing: Whimsical Mind Maps


How to Build an Animated CSS Thermometer Chart


Death of IE; its Aftermath on Cross Browser Compatibility


Vivaldi 2.6


Gitting your First Dev Job


Building a Component Library Using Figma


Sustainable Web Manifesto


What are Design Systems and Why do You Need One?


Do Animations Deliver a Better User Experience?


A Complete Guide to Iconography


Adobe has an Ambitious Plan to Help the Public Spot Fake Images


Drop Caps & Design Systems


Thinking Beyond Screens


Optimizing Google Fonts Performance


Baseline Grid


Want more? No problem! Keep track of top design news from around the web with Webdesigner News.

Add Realistic Chalk and Sketch Lettering Effects with Sketch’it – only $5!

p img {display:inline-block; margin-right:10px;}
.alignleft {float:left;}
p.showcase {clear:both;}
body#browserfriendly p, body#podcast p, div#emailbody p{margin:0;}

Reduced Motion Picture Technique, Take Two

Did you see that neat technique for using the <picture> element with <source media=""> to serve an animated image (or not) based on a prefers-reduced-motion media query?

After we shared that in our newsletter, we got an interesting reply from Michael Gale:

What about folks who love their animated GIFs, but just didn’t want the UI to be zooming all over the place? Are they now forced to make a choice between content and UI?

I thought that was a pretty interesting question.

Also, whenever I see <img src="gif.gif"> these days, my brain is triggered into WELL WHAT ABOUT MP4?! territory, as I’ve been properly convinced that videos are better-in-all-ways on the web than GIFs. Turns out, some browsers support videos right within the <img> element and, believe it or not, you can write fallbacks for that, with — drumroll, please — for the <picture> element as well!

Let’s take a crack at combining all this stuff.

Adding an MP4 source

The easy one is adding an additional <source> with the video. That means we’ll need three source media files:

  1. A fallback non-animated graphic when prefers-reduced-motion is reduce.
  2. An animated GIF as the default.
  3. An MP4 video to replace the GIF, if the fallback is supported.

For example:

<picture> <source srcset="static.png" media="(prefers-reduced-motion: reduce)"></source> <source srcset="animated.mp4" type="video/mp4"> <img srcset="animated.gif" alt="animated image" />

Under default conditions in Chrome, only the GIF is downloaded and shown:

Chrome DevTools showing only gif downloaded

Under default conditions in Safari, only the MP4 is downloaded and shown:

Safari DevTools showing only mp4 downloaded

If you’ve activated prefers-reduced-motion: reduce in either Chrome or Safari (on my Mac, I go to System PreferencesAccessibilityDisplayReduce Motion), both browsers only download the static PNG file.

Chrome DevTools showing png downloaded

I tested Firefox and it doesn’t seem to work, instead continuing to download the GIF version. Firefox seems to support prefers-reduced-motion, but perhaps it’s just not supported on <source> elements yet? I’m not sure what’s up there.

Wouldn’t it be kinda cool to provide a single animated source and have a tool generate the others from it? I bet you could wire that up with something like Cloudinary.

Adding a toggle to show the animated version

Like Michael Gale mentioned, it seems a pity that you’re entirely locked out from seeing the animated version just because you’ve flipped on a reduced motion toggle.

It should be easy enough to have a <button> that would use JavaScript to yank out the media query and force the browser to show the animated version.

I’m fairly sure there is no practical way to do this declaratively in HTML. We also can’t put this button within the <picture> tag. Even though <picture> isn’t a replaced element, the browser still gets confused and doesn’t like it. Instead, it doesn’t render it at all. No big deal, we can use a wrapper.

We can position the button on top of the image somewhere. This is just an arbitrary choice — you could put it wherever you want, or even have the entire image be tappable as long as you think you could explain that to users. Remember to only show the button when the same media query matches:

.picture-wrap .animate-button { display: none;
} @media (prefers-reduced-motion: reduce) { .picture-wrap .animate-button { display: block; }

When the button is clicked (or tapped), we need to remove the media query to start the animation by downloading an animated source.

let button = document.querySelector(".animate-button"); button.addEventListener("click", () => { const parent = button.closest(".picture-wrap"); const picture = parent.querySelector("picture"); picture.querySelector("source[media]").remove();

Here’s that in action:

See the Pen
Prefers Reduction Motion Technique PLUS!
by Chris Coyier (@chriscoyier)
on CodePen.

Maybe this is a good component?

We could automatically include the button, the button styling, and the button functionality with a web component. Hey, why not?

See the Pen
Prefers Reduction Motion Technique as Web Component
by Chris Coyier (@chriscoyier)
on CodePen.

The post Reduced Motion Picture Technique, Take Two appeared first on CSS-Tricks.

Weekly Platform News: Mozilla’s AV1 Encoder, Samsung One UI CSS, DOM Matches Method

Šime posts regular content for web developers on

In this week’s weekly roundup, Vimeo and Mozilla partner up on a video encoding format, how to bind instructions to to form fields using aria labels, the DOM has a matching function, and Samsung is working on its own CSS library.

Vimeo partners with Mozilla to use their rav1e encoder

Vittorio Giovara: AV1 is a royalty-free video codec designed by the Alliance for Open Media and the the most anticipated successor of H.264. Vimeo is contributing to the development of Mozilla’s AV1 encoder.

In order for AV1 to succeed, there is a need of an encoder like x264, a free and open source encoder, written by the community, for the community, and available to everyone: rav1e. Vimeo believes in what Mozilla is doing.

Use aria-describedby to bind instructions to form fields

Raghavendra Satish Peri: If you provide additional instructions for a form field, use the aria-describedby attribute to bind the instruction to the field. Otherwise, assistive technology users who use the Tab key might miss this information.

<label for="dob">Date of Birth</label>
<input type="text" aria-describedby="dob1" id="dob" />
<span id="dob1">Use DD/MM/YY</span>

Samsung Internet announces One UI CSS

Diego González: Samsung is experimentally developing a CSS library based on its new One UI design language. The library is called One UI CSS and includes styles for common form controls such as buttons, menus, and sliders, as well as other assets (web fonts, SVG icons, polyfills).

Some of the controls present in One UI CSS.

DOM elements have a matches method

Sam Thorogood: You can use the matches method to test if a DOM element has a specific CSS class, attribute or ID value. This method accepts a CSS selector and returns true if the element matches the given selector.

el.classList.has('foo') /* becomes */ el.matches('.foo');
el.hasAttribute('hello') /* becomes */ el.matches('[hello]'); === 'bar' /* becomes */ el.matches('#bar');

The post Weekly Platform News: Mozilla’s AV1 Encoder, Samsung One UI CSS, DOM Matches Method appeared first on CSS-Tricks.

Design Your Mobile Emails To Increase On-Site Conversion

Design Your Mobile Emails To Increase On-Site Conversion

Design Your Mobile Emails To Increase On-Site Conversion

Suzanne Scacca

I find it interesting that Google has pushed so hard for web designers to shift from designing primarily for desktop to now designing primarily for mobile. Google’s right… but why only focus on designing websites to appeal to mobile users? After all, Gmail is a leader within the email client ranks, too.

Email can be an incredibly powerful driver of conversions for websites, according to a 2019 report from Barilliance.

On average, emails convert at a rate of 1.48%. That includes all sent emails though — which includes the ones that go unopened as well as the ones that bounce. If you look at emails that are opened by recipients, however, the average conversion rate jumps to 17.75%.

Let’s go even further with this:

Recent data from Litmus reveals that more emails are opened on mobile than on any other device:

Litmus email opens data
Litmus data reveals that 43% of email opens occur on mobile devices. (Source: Litmus) (Large preview)

Many sources even put the average mobile open rate at well over 50%. But whether it’s 43% or 50%+, it’s clear that mobile is most commonly the first device people reach for to check their emails.

Which brings us to the following conclusion:

If users are more likely to open email on mobile and we know that opened emails convert at a higher rate than those that go unopened, wouldn’t it make sense for designers to prioritize the mobile experience when designing emails?

Mobile Email Design Tips to Increase Conversions

Let’s explore what the latest research says about designing emails for mobile users and how that can be used to increase opens, clicks and, later, your website’s conversion rates (on mobile and desktop).

Design the Same Email for Mobile and Desktop

Although email is often ranked as the most effective marketing channel for acquiring and retaining customers, that’s not really an accurate picture of what’s going on.

According to Campaign Monitor, here’s what’s actually happening with mobile email subscribers:

Campaign Monitor mobile CTR data
Campaign Monitor charts the progression from mobile email opens to click-through rate. (Source: Campaign Monitor) (Large preview)

The open rates on mobile are somewhat on par with the Litmus data earlier.

However, it can take multiple opens before the email recipient actually clicks on a link or offer within an email. And guess what? About a third of them make their way over to desktop — where they convert at a higher rate than those that stay on mobile.

As the report states:

Data from nearly 6 million email marketing campaigns suggests the shift to mobile has made it more difficult to get readers to engage with your content, unless you can drive subsequent opens in a different environment.

I’ve reconstructed the graphic above and filled it with the number of people who would take action from an email list of 1,000 recipients:

Campaign Monitor mobile open and click data
An example of how Campaign Monitor’s data translates into real-world numbers. (Source: Campaign Monitor) (Large preview)

At first glance, it looks as though mobile is the clear winner — at least in terms of driving traffic to the website. After the initial mobile open, 32 subscribers go straight to the website. After a few more opens on mobile, 5 more head over there.

Without a breakdown of what the user journey looks like when opened on desktop, though, the calculation of additional clicks you’d get from that portion of the list isn’t so cut-and-dried.

However, let’s assume that Litmus’s estimate of 18% desktop opens is accurate and that Campaign Monitor’s 12.9% click-through rate holds true whether they open the email first on mobile or desktop. I think it’s safe to say that 23 desktop-only email opens can be added to the total.

So, that brings it to:

37 clicks on mobile vs 26 on desktop.

Bottom line: while mobile certainly gets more email subscribers over to a website, the conversion-friendliness of desktop cannot be ignored.

Which is why you don’t want to segment your lists based on device. If you want to maximize the number of conversions you get from a campaign, enable subscribers to seamlessly move from one device to the other as they decide what action to take with your emails.

In other words, design the same exact email for desktop and mobile. But assume that the majority of subscribers will open the email on their mobile device (unless historical data of your campaigns says otherwise). Then, use mobile-first design and marketing tips to create an email that’s suitable for all subscribers, regardless of device.

Factor in Dark Mode When Choosing Your Colors

You don’t want there to be anything that stands in your users’ way when it comes to moving from email to website. That’s why you have to consider how their choice of color and brightness for their mobile screen affects the readability or general appearance of your email design.

There are a number of ways in which this can become an issue.

As we hear more and more about how harmful blue light from our devices can be, it’s no surprise that Dark Mode options are beginning to roll out. While it’s prevalent on desktops right now, it’s mostly in beta for mobile. The same goes for email apps.

That said, smartphone users can hack their own “Dark Mode” of sorts. This type of color inversion can be enabled through the iPhone’s “Accessibility” settings.

Gadget Hacks iPhone 'Dark Mode' hack
Gadget Hacks shows how iPhone users can hack their own ‘Dark Mode’. (Source: Gadget Hacks) (Large preview)

Essentially, what this does is invert all of the colors on the screen from light to dark and vice versa.

Unfortunately, the screenshotting tool on my iPhone won’t allow me to capture the colors exactly as they appear. However, what I can show you is how the inversion tool alters the color of your email design.

This is an email I received from Amtrak last week. It’s pretty standard with its branded color palette and brightly colored notices and CTA buttons:

Amtrak email on Gmail mobile app
What a promotional email from Amtrak looks like on the Gmail mobile app. (Source: Amtrak) (Large preview)

Now, here is what that same email looks like when viewed through my iPhone’s “Smart Invert” setting:

Amtrak email with inverted colors
What a promotional email from Amtrak looks like in Gmail when colors are inverted. (Source: Amtrak) (Large preview)

The clean design of the original with the white font on the deep blue brand colors is gone. Now, there’s a harsh mix of colors and a hard-to-read Amtrak logo in its place.

You can imagine how this kind of inconsistent and disjointed color display would create an off-putting experience for mobile users.

But what do you expect them to do? If they’re struggling with the glare from their mobile device, Dark Mode (or some other brightness adjustment) will make it easier for them to open and read emails in the first place. Even if it means compromising the appearance of the email you so carefully designed.

One bright spot in all this is that the official “Dark Mode” being rolled out to iPhone (and, hopefully, other smartphones) soon won’t alter the look of HTML emails. Only plain-text messages will be affected.

However, it’s important to still be mindful of how the design choices you make may clash with a surrounding black background. Brightly colored backgrounds, in particular, are likely to clash with the surrounding black of your email app.

How do you solve this issue? Unfortunately, you can’t serve different versions of your email to users based on whether they’re viewing it in Dark Mode or otherwise. You’ll just have to rely on your own tests to confirm that potential views in Dark Mode don’t interfere with your design or message.

In addition to the standard testing you do, set your own smartphone up with Dark Mode (or its hack counterpart). Then, run your test email through the filter and see what happens to the colors. It won’t take long to determine what sort of colors you can and cannot design with for email.

Design the Subject Line

The subject line is the very first thing your email subscribers are going to see, whether it shows up as a push notification or they first encounter it in their inbox. What do you think affects their initial decision to click open an email rather than throw it in the Trash or Spam box immediately? Recognizing the Sender will help, but so will the attractiveness of the subject line.

As for how exactly you go about “designing” a subject line, there are a few things to think about. The first is the length.

Marketo conducted a study across 200+ email campaigns and 2 million emails sent to subscribers. Here is what the test revealed about subject line length:

Marketo subject line length test
Marketo tested over 2 million sent emails to determine the ideal subject line length. (Source: Marketo) (Large preview)

Although the 4-word subject line resulted in the highest open rate, it had a poor showing in terms of clicks. It was actually the 7-word subject line that seemed to have struck the perfect balance with subscribers, leading 15.2% of them to open the email and then 10.8% of them to click on it.

While you should still test this with your own email list, it appears that seven words is the ideal length for a subject line.

Next, you have to think about the buzzwords used in the subject line.

To start, keep this list of Yesware’s Spam Trigger Words out of it:

Yesware list of spam-trigger words
Yesware’s analysis and list of the top spam-trigger words. (Source: Yesware) (Large preview)

If you want to increase the chance the email will be opened, read, clicked on and eventually convert on-site, you have to be savvy about which words will appear within the subject line.

What I’d suggest you do is bookmark CoSchedule’s Email Subject Line Tester tool.

CoSchedule email subject line tester
CoSchedule tests and scores your email subject lines with one click. (Source: CoSchedule) (Large preview)

Here’s an example of how CoSchedule analyzes your subject lines and clues you in to what increases and decreases your open rates:

CoSchedule subject line score
The first part of CoSchedule’s subject line analysis and scoring tool. (Source: CoSchedule) (Large preview)

As you can see, CoSchedule tells you which kinds of words increase open rates as well as those that don’t. Do enough of these subject line tests and you should be able to compile a good set of wording guidelines for your writers and marketers.

Further down, you’ll get more insight into what makes for a strongly worded and designed subject line:

CoSchedule subject line recommendations
The second part of CoSchedule’s subject line assessment and recommendations. (Source: CoSchedule) (Large preview)

CoSchedule will provide recommendations on how to shorten or lengthen the character and word counts based on best practices and results.

Finally, at the very bottom of your subject line test you’ll see this:

CoSchedule email client preview
The final part of CoSchedule’s subject line tester includes an email client preview. (Source: CoSchedule) (Large preview)

This gives you (or, rather, your writer) a chance to see how the subject line will appear within the “design” of an email client. It’s not a problem if the words get cut off on mobile. It’s bound to happen. However, you still want everything that does appear to be appealing enough to click on.

Also, don’t forget about dressing up your subject lines with emoji.

When you think about it, emoji in mobile email subject lines make a lot of sense. Text messaging and social media are ripe with them. It’s only natural to use this fun and truncated form of language in email, too.

Campaign Monitor makes a good point about this:

If you replace words with recognizable emoji, you’ll create shorter subject lines for mobile users. Even if it doesn’t shorten your subject line enough to fit on a mobile screen, it’s still an awesome way to make it stand out from the rest of your subscribers’ cluttered inboxes.

The CoSchedule test will actually score you based on how (or if) you used emoji, too:

CoSchedule Emoji Evaluation
CoSchedule suggests that the use of emoji in subject lines will give you an edge. (Source: CoSchedule) (Large preview)

As you can see, CoSchedule considers this a competitive advantage in marketing.

Even just looking at my own email client, my eye is instantly drawn to the subject line from Sephora which contains a “NEW” emoji:

Sephora subject line with emoji
A Sephora email containing an emoji stands out from others in the inbox. (Source: Sephora) (Large preview)

Just be careful with which emoji you use. For starters, emoji are displayed differently from device to device, so it may not have the same effect on some of your subscribers if it’s a more obscure choice.

There’s also the localization aspect to think about. Not every emoji is perceived the same way around the globe. As Day Translations points out, the fire symbol is one that could cause confusion as some countries interpret it as a literal fire whereas some may view it as a symbol for attraction.

That said, emoji have proven to increase both open rates and read rates of emails. Find the right mobile-friendly emoji to include in your subject line and you could effectively increase the number of subscribers who visit your website as a result.


There are so many different kinds of emails that go out from websites:

  • Welcome message
  • Post-purchase transaction email
  • Abandoned cart reminder
  • Promotional news
  • Product featurette
  • New content available
  • Account /rewards points
  • And more.

In other words, there are plenty of ways to get in front of email subscribers.

Just remember that the majority of them will first open your email on mobile. And some will reopen it on mobile over and over again until they’re compelled to click on it or trash it. It’s up to you to design the email in a way that motivates them to visit your website and, consequently, convert.

Further Reading on SmashingMag:

Smashing Editorial (ra, yk, il)
Managing WordPress Metadata in Gutenberg Using a Sidebar Plugin

WordPress released their anticipated over to the post editor, nicknamed Gutenberg, which is also referred to as the block editor. It transforms a WordPress post into a collection of blocks that you can add, edit, remove and re-order in the layout. Before the official release, Gutenberg was available as a plugin and, during that time, I was interested in learning how to create custom blocks for the editor. I was able to learn a lot about Gutenberg that I decided to put together a course that discusses almost everything you need to know to develop blocks for Gutenberg.

In this article, we will discuss metaboxes and metafields in WordPress. Specifically, we’ll cover how to replace the old PHP metaboxes in Gutenberg and extend Gutenberg’s sidebar to add a React component that will be used to manipulate the metadata using the global JavaScript Redux-like stores. Note that metadata in Gutenberg can also be manipulated using blocks. And both ways are discussed in my course, however, in this article I am going to focus on managing metadata in the sidebar since I believe this method will be used more often.

This article assumes some familiarity with ReactJS and Redux. Gutenberg relies heavily on these technologies to render UI and manage state. You can also check out the CSS-Tricks guide to learning Gutenberg for an intro to some of the concepts we’ll cover here.

The block editor interface

Gutenberg is a React application

At its core, Gutenberg is a ReactJS application. Everything you see in the editor is rendered using a React component. The post title, the content area that contains the blocks, the toolbar at the top and the right sidebar are all React components. Data or application states in this React application are stored in centralized JavaScript objects, or “stores.” These stores are managed by WordPress’ data module. This module shares a lot of core principles with Redux. So, concepts like stores, reducers, actions, action creators, etc., also exist in this module. I will sometimes refer to these stores as “Redux-like” stores.

These stores do not only store any data about the current post, like the post content (the blocks), the post title, and the selected categories, but it also stores global information about a WordPress website, like all the categories, tags, posts, attachments and so on. In addition to that, UI state information like,”is the sidebar opened or closed?” are also stored in these global stores. One of the jobs of the “data module” is to retrieve data from these stores and also change data in the stores. Since these stores are global and can be used by multiple React components changing data in any store will be reflected in any Gutenberg UI part (including blocks) that uses this piece of data.

Once a post is saved, the WordPress REST API will be used to update the post using the data stored in these global stores. So the post title, the content, categories etc., that are stored in these global stores will be sent as payload in the WP REST API endpoint that updates the post. And thus if we are able to manipulate data in these stores, once the user clicks save, the data that we manipulated will be stored in the database by the API without us having to do anything.

One of the things that is not managed by these global stores in Gutenberg is metadata. If you have some metafields that you used to manage using a metabox in the pre-Gutenberg “classic” editor, those will not be stored and manipulated using the global Redux-like stores by default. However, we can opt-in to manage metadata using JavaScript and the Redux-like stores. Although those old PHP metaboxes will still appear in Gutenberg, WordPress recommends porting these PHP metaboxes to another approach that uses the global stores and React components. And this will ensure a more unified and consistent experience. You can read more about problems that could occur by using PHP metaboxes in Gutenberg.

So before we start, let’s take a look at the Redux-like stores in Gutenberg and how to use them.

Retrieving and changing data in Gutenberg’s Redux-like stores

We now know that the Gutenberg page is managed using these Redux-like stores. We have some default “core” stores that are defined by WordPress. Additionally, we can also define our own stores if we have some data that we would like to share between multiple blocks or even between blocks and other UI elements in the Gutenberg page, like the sidebar. Creating your own stores is also discussed in my course and you can read about it in the official docs. However, in this article we will focus on how to use the existing stores. Using the existing stores lets us manipulate metadata; therefore we will not need to create any custom stores.

In order to access these stores, make sure you have the latest WordPress version with Gutenberg active and edit any post or page. Then, open your browser console an type the following statement:'core/editor').getBlocks()

You should get something like this:

Let’s break this down. First, we access the module which (as we discussed) is responsible for managing the Redux-like stores. This module will be available inside the global wp variable if you have Gutenberg in your WordPress installation. Then, inside this module, we call a function called select. This function receives a store name as an argument and returns all the selectors for this store. A selector is a term used by the data module and it simply means a function that gets some data from the store. So, in our example, we accessed the core/editor store, and this will return a bunch of functions that can be used to get data from this store. One of these functions is getBlocks() which we called above. This function will return an array of objects where each object represents a block in your current post. So depending on how many blocks you have in your post, this array will change.

As we’ve seen, we accessed a store called core/editor. This store contains information about the current post that you are editing. We’ve also seen how to get the blocks in the current post but we can also get a lot of other stuff. We can get the title of the current post, the current post ID, the current post post type and pretty much everything else we might need.

But in the example above, we were only able to retrieve data. What if we want to change data? Let’s take a look at another selector in the ‘core/editor’ store. Let’s run this selector in our browser console:'core/editor').getEditedPostAttribute('title')

This should return the title of the post currently being edited:

Great! Now what if we want to change the title using the data module? Instead of calling select(), we can call dispatch() which will also receive a store name and return some actions that you can dispatch. If you are familiar with Redux, terms like “actions” and “dispatch” will sound familiar to you. If this sounds new to you, all you need to know is that dispatching a certain action simply means changing some data in a store. In our case, we want to change the post title in the store, so we can call this function:'core/editor').editPost({title: 'My new title'})

Now take a look at the post title in the editor — it will be changed accordingly!

That’s how we can manipulate any piece of data in the Gutenberg interface. Wan retrieve the data using selectors and change that data using actions. Any change will be reflected in any part of the UI that uses this data.

There are, of course, other stores in Gutenberg that you can checkout on this page. So, let’s take a quick look at a couple of more stores before we move on.

The stores that you will use the most are the core/editor which we just looked at, and the core store. Unlike core/editor, the core store contains information, not only about the currently edited post, but also about the whole WordPress website in general. So, for instance, we can get all the authors on the website using:'core').getAuthors()

We can also get some posts from the website like so:'core').getEntityRecords('postType','post',{per_page: 5})

Make sure to run this twice if the first result was null. Some selectors like this one will send an API call first to get your post. That means the the returned value will initially be null until the API request is fulfilled:

Let’s look at one more store: edit-post. This store is responsible for the UI information in the actual editor. For example, we can have selectors that check if the sidebar is currently open:'core/edit-post').isEditorSidebarOpened()

This will return true if the sidebar is opened. But try closing the sidebar, run this function again, and it should return false.

We can also open and close the sidebar by dispatching actions in this store. Having the sidebar open and running this action in the browser console, the sidebar should be closed:'core/edit-post').closeGeneralSidebar()

You will unlikely need to use this store, but it’s good to know that this is what Gutenberg does when you click on the sidebar icon to close it.

There are some more stores that you might need to take a look at. The core/notices store, for instance, could be useful. This can help you display error, warning and success messages in the Gutenberg page. You can also check all the other stores here.

Try to play around with these stores in your browser until you feel comfortable using them. After that, we can see how to use them in real code outside the browser.

Let’s setup a WordPress plugin to add a Gutenberg sidebar

Now that we know how to use the Redux-like stores in Gutenberg, the next step is to add a React sidebar component in the editor. This React component will be connected to the core/editor store and it will have some input that, when changed, will dispatch some action that will manipulate metadata — like the way we manipulated the post title earlier. But to do that, we need to create a WordPress plugin that holds our code.

You can follow along by cloning or downloading the repository for this example on GitHub.

Let’s create a new folder inside wp-content/plugins directory of the WordPress installation. I am going to call it gutenberg-sidebar. Inside this folder, let’s create the entry point for our plugin. The entry point is the PHP file that will be run when activating your plugin. It can be called index.php or plugin.php. We’re going to use plugin.php for this example and put some information about the plugin at the top as well as add some code that avoids direct access:

/** * Plugin Name: gutenberg-sidebar * Plugin URI: * Description: Sidebar for the block editor. * Author: Ali Alaa * Author URI: */
if( ! defined( 'ABSPATH') ) { exit;

You should find your plugin on the Plugins screen in the WordPress admin. Click on “Activate” in order for the code to run.

As you might imagine, we will write a lot of JavaScript and React from this point, forward. And in order to code React components easily we will need to use JSX. And JSX is not valid JavaScript that can run in your browser, it needs to be converted into plain JavaScript. We might also need to use ESNext features and import statements for importing and exporting modules.

And these features will not work on all browsers, so it’s better to transform our code into old ES5 JavaScript. Thankfully, there are a lot of tools that can help us achieve that. A famous one is webpack. webpack, however, is a big topic in itself and it won’t fit the scope of this article. Therefore, we are going to use another tool that WordPress provides which is @wordpress/scripts. By installing this package, we will get a recommended webpack configuration without having to do anything in webpack ourselves. Personally, I recommend that you learn webpack and try to do the configuration yourself. This will help you understand what’s going on and give you more control. You can find a lot of resources online and it’s also discussed in my course. But for now, let’s install the WordPress webpack configuration tool.

Change to your plugin folder in Terminal:

cd path/to/your/theme/folder

Next, we need to initialize npm in that folder in order to install @wordpress/scripts. This can be done by running this command:

npm init

This command will ask you some questions like the package name, version, license, etc. You can keep hitting Enter and leave the default values. You should have a package.json file in your folder and we can start installing npm packages. Let’s install @wordpress/scripts by running the following command:

npm install @wordpress/scripts --save-dev

This package will expose a CLI called wp-scripts which you can use in your npm scripts. There are different commands that you can run. We will focus on the build and start commands for now. The <code>build script will transform your files so that they are minified and ready for production. Your source code’s entry point is configured in src/index.js and the transformed output will be at build/index.js. Similarly, the start script will transform your code in src/index.js to build/index.js, however, this time, the code will not be minified to save time and memory — the command will also watch for changes in your files and re-build your files every time something is changed. The start command is suitable to be used for development while the build command is for production. To use these commands, we will replace the scripts key in the package.json file which will look something like this if you used the default options when we initialized npm.

Change this:

"scripts": { "test": "echo "Error: no test specified" && exit 1"

…to this:

"scripts": { "start": "wp-scripts start", "build": "wp-scripts build"

Now we can run npm start and npm run build to start development or build files, respectively.

Let’s create a new folder in the plugin’s root called src and add an index.js file in it. We can see it things are working by sprinkling in a little JavaScript. We’ll try an alert.

Now run npm start in Terminal. You should find the build folder created with the compiled index.js and also sourcemap files. In addition to that, you will notice that the build/index.js file is not minified and webpack will be watching for changes. Try changing the src/index.js file and save again. The build/index.js file will re-generated:

If you stop the watch (Ctrl + C ) in Terminal and run npm run build, the build/index.js file should now be minified.

Now that we have our JavaScript bundle, we need to enqueue this file in the Gutenberg editor. To do that we can use the hoo enqueue_block_editor_assets which will insure that the files are enqueued only in the Gutenberg page and not in other wp-admin pages where it isn’t needed.

We can enqueue our file like so in plugin.php:

// Note that it’s a best practice to prefix function names (e.g. myprefix)
function myprefix_enqueue_assets() { wp_enqueue_script( 'myprefix-gutenberg-sidebar', plugins_url( 'build/index.js', __FILE__ ) );
add_action( 'enqueue_block_editor_assets', 'myprefix_enqueue_assets' );

Visit the Gutenberg page. If all is well, you should get an alert, thanks to what we added to src/index.js earlier.

Fantastic! We’re ready to write some JavaScript code, so let’s get started!

Importing WordPress JavaScript packages

In order to add some content to the existing Gutenberg sidebar or create a new blank sidebar, we need to register a Gutenberg JavaScript plugin — and in order to do that, we need to use some functions and components from packages provided by WordPress: wp-plugins, wp-edit-post and wp-i18n. These packages will be available in the wp global variable in the browser as wp.plugins, wp.editPost and wp.i18n.

We can import the functions that we need into src/index.js. Specifically, those functions are: registerPlugin and PluginSidebar.

const { registerPlugin } = wp.plugins;
const { PluginSidebar } = wp.editPost;
const { __ } = wp.i18n;

It’s worth noting that we need to make sure that we have these files as dependencies when we enqueue our JavaScript file in order to make sure that our index.js file will be loaded after the wp-plugins, wp-edit-posts and wp-i18n packages. Let’s add those to plugin.php:

function myprefix_enqueue_assets() { wp_enqueue_script( 'myprefix-gutenberg-sidebar', plugins_url( 'build/index.js', __FILE__ ), array( 'wp-plugins', 'wp-edit-post', 'wp-i18n', 'wp-element' ) );
add_action( 'enqueue_block_editor_assets', 'myprefix_enqueue_assets' );

Notice that I added wp-element in there as a dependency. I did that because we will write some React components using JSX. Typically, we’d import the entire React library when making React components. However, wp-element is an abstraction layer atop React so we never have to install or import React directly. Instead, we use wp-element as a global variable.

These packages are also available as npm packages. Instead of importing functions from the global wp variable (which will only be available in the browser that your code editor knows nothing about), we can simply install these packages using npm and import them in our file. These WordPress packages are usually prefixed with @wordpress.

Let’s install the two packages that we need:

npm install @wordpress/edit-post @wordpress/plugins @wordpress/i18n --save

Now we can import our packages in index.js:

import { registerPlugin } from "@wordpress/plugins";
import { PluginSidebar } from "@wordpress/edit-post";
import { __ } from "@wordpress/i18n";

The advantage of importing the packages this way is that your text editor knows what @wordpress/edit-post and @wordpress/plugins are and it can autocomplete functions and components for you — unlike importing from wp.plugins and wp.editPost which will only be available in the browser while the text editor has no clue what wp is.

Your text editor can autocomplete component names for you.

You might also think that importing these packages in your bundle will increase your bundle size, but there’s no worries there. The webpack config file that comes with @wordpress/scripts is instructed to skip bundling these @wordpress packages and depend of the wp global variable instead. As a result, the final bundle will not actually contain the various packages, but reference them via the wp variable.

Great! so I am going to stick to importing packages using npm in this article, but you are totally welcome to import from the global wp variable if you prefer. Let’s now use the functions that we imported!

Registering a Gutenberg Plugin

In order to add a new custom sidebar in Gutenberg, we first need to register a plugin — and that’s what the registerPlugin function that we imported will do. As a first argument, registerPlugin will receive a unique slug for this plugin. We can have an array of options as a second argument. Among these options, we can have an icon name (from the dashicons library) and a render function. This render function can return some components from the wp-edit-post package. In our case. we imported the PluginSidebar component from wp-edit-post and created a sidebar in the Gutenberg editor by returning this component in the render function. I also added PluginSidebar inside a React fragment since we can add other components in the render function as well. Also, the __ function imported from wp-i18n will be used so we can translate any string that we output:

registerPlugin( 'myprefix-sidebar', { icon: 'smiley', render: () => { return ( <> <PluginSidebar title={__('Meta Options', 'textdomain')} > Some Content </PluginSidebar> </> ) }

You should now have a new icon beside the cog icon in the Gutenberg editor screen. This smiley icon will toggle our new sidebar which will have whatever content we have inside the PluginSidebar component:

If you were to click on that star icon beside the sidebar title, the sidebar smiley icon will be removed from the top toolbar. Therefore, we need to add another way to access our sidebar in case the user un-stars it from the top toolbar, and to do that, we can import a new component from wp-edit-post called PluginSidebarMoreMenuItem. So, let’s modify out import statement:

import { PluginSidebar, PluginSidebarMoreMenuItem } from "@wordpress/edit-post";

The PluginSidebarMoreMenuItem will allow us to add an item in the Gutenberg menu that you can toggle using the three dots icon at the top-right of the page. We want to modify our plugin to include this component. We need to give PluginSidebar a name prop and give PluginSidebarMoreMenuItem a target prop with the same value:

registerPlugin( 'myprefix-sidebar', { icon: 'smiley', render: () => { return ( <> <PluginSidebarMoreMenuItem target="myprefix-sidebar" > {__('Meta Options', 'textdomain')} </PluginSidebarMoreMenuItem> <PluginSidebar name="myprefix-sidebar" title={__('Meta Options', 'textdomain')} > Some Content </PluginSidebar> </> ) }

In the menu now, we will have a “Meta Options” item with our smiley icon. This new item should toggle our custom sidebar since they are linked using the name and the target props:

Great! Now we have a new space in our Gutenberg page. We can replace the “some content” text in PluginSidebar and add some React components of our own!

Also, let’s make sure to check the edit-post package documentation. This package contains a lot of other components that you can add in your plugin. These components can allow you to extend the existing default sidebar and add your own components in it. Also, we can find components that allow us to add items in the Gutenberg top-right menu and also for the blocks menu.

Handling metadata in the classic editor

Let’s take a quick look at how we used to manage metadata in the classic editor using metaboxes. First, install and activate the classic editor plugin in order to switch back to the classic editor. Then, add some code that will add a metabox in the editor page. This metabox will manage a custom field that we’ll call _myprefix_text_metafield. This metafield will just be a text field that accepts HTML markup. You can add this code in plugin.php or put it in a separate file and include it plugin.php:

function myprefix_add_meta_box() { add_meta_box( 'myprefix_post_options_metabox', 'Post Options', 'myprefix_post_options_metabox_html', 'post', 'normal', 'default' );
add_action( 'add_meta_boxes', 'myprefix_add_meta_box' );
function myprefix_post_options_metabox_html($post) { $field_value = get_post_meta($post->ID, '_myprefix_text_metafield', true); wp_nonce_field( 'myprefix_update_post_metabox', 'myprefix_update_post_nonce' ); ?> <p> <label for="myprefix_text_metafield"><?php esc_html_e( 'Text Custom Field', 'textdomain' ); ?></label> <br /> <input class="widefat" type="text" name="myprefix_text_metafield" id="myprefix_text_metafield" value="<?php echo esc_attr( $field_value ); ?>" /> </p> <?php
function myprefix_save_post_metabox($post_id, $post) { $edit_cap = get_post_type_object( $post->post_type )->cap->edit_post; if( !current_user_can( $edit_cap, $post_id )) { return; } if( !isset( $_POST['myprefix_update_post_nonce']) || !wp_verify_nonce( $_POST['myprefix_update_post_nonce'], 'myprefix_update_post_metabox' )) { return; } if(array_key_exists('myprefix_text_metafield', $_POST)) { update_post_meta( $post_id, '_myprefix_text_metafield', sanitize_text_field($_POST['myprefix_text_metafield']) ); }
add_action( 'save_post', 'myprefix_save_post_metabox', 10, 2 );

I am not going to go into details in this code since this is out of the scope of the article, but what it’s essentially doing is:

  • Making a metabox using the add_meta_box function
  • Rendering an HTML input using the myprefix_post_options_metabox_html function
  • Controlling the metafield, called _myprefix_text_metafield
  • Using the save_post action hook to get the HTML input value and update the field using update_post_meta.

If you have the classic editor plugin installed, then you should see the metafield in the post editor:

Note that the field is prefixed with an underscore (_myprefix_text_metafield) which prevents it from being edited using the custom fields metabox that comes standard in WordPress. We add this underscore because we intend to manage the field ourselves and because it allows us to hide it from the standard Custom Fields section of the editor.

Now that we have a way to manage the field in the classic editor, let’s go ahead and deactivate the classic editor plugin and switch back to Gutenberg. The metabox will still appear in Gutenberg. However, as we discussed earlier, WordPress recommends porting this PHP-based metabox using a JavaScript approach.

That’s what we will do in the rest of the article. Now that we know how to use the Redux-like stores to manipulate data and how to add some React content in the sidebar, we can finally create a React component that will manipulate our metafield and add it in the sidebar of the Gutenberg editor.

We don’t want to completely get rid of the PHP-based field because it’s still helpful in the event that we need to use the classic editor for some reason. So, we’re going to hide the field when Gutenberg is active and show it when the classic editor is active. We can do that by updating the myprefix_add_meta_box function to use the __back_compat_meta_box option:

function myprefix_add_meta_box() { add_meta_box( 'myprefix_post_options_metabox', 'Post Options', 'myprefix_post_options_metabox_html', 'post', 'normal', 'default', array('__back_compat_meta_box' => true) );

Let’s move on to creating the React component that manages the metadata.

Getting and setting metadata using JavaScript

We have seen how to get the post title and how to change it using the wp-data module. Let’s take a look at how to do the same for custom fields. To get metafields, we can call the save selector getEditedPostAttribute. But this time we will pass it a value of meta instead of title.

Once that’s done, test it out in the browser console:'core/editor').getEditedPostAttribute('meta')

As you will see, this function will return an empty array, although we are sure that we have a custom field called _myprefix_text_metafield that we are managing using the classic editor. To make custom fields manageable using the data module, we first have to register the field in the plugin.php.

function myprefix_register_meta() { register_meta('post', '_myprefix_text_metafield', array( 'show_in_rest' => true, 'type' => 'string', 'single' => true, ));
add_action('init', 'myprefix_register_meta');

Make sure to set the show_in_rest option to true. WordPress will fetch the fields using the WP REST API. That means, we need to enable the show_in_rest option to expose it.

Run the console test again and we will have an object with all of our custom fields returned.

Amazing! We are able to get our custom field value, so now let’s take a look at how can we change the value in the store. We can dispatch the editPost action in the core/editor store and pass it an object with a meta key, which will be another object with the fields that we need to update:'core/editor').editPost({meta: {_myprefix_text_metafield: 'new value'}})

Now try running the getEditedPostAttribute selector again and the value should be updated to new value.

If you try saving a post after updating the field using Redux, you will get an error. And if you take a look at the Network tab in DevTools, you will find that the error is returned from the wp-json/wp/v2/posts/{id} REST endpoint that says that we are not allowed to update _myprefix_text_metafield.

This because WordPress treats any field that is prefixed with an underscore as a private value that cannot be updated using the REST API. We can, however, specify an auth_callback option that will allow updating this field using the REST API when it returns true as long as the editor is capable of editing posts. We can also add the sanitize_text_field function to sanitize the value before saving to the database:

function myprefix_register_meta() { register_meta('post', '_myprefix_text_metafield', array( 'show_in_rest' => true, 'type' => 'string', 'single' => true, 'sanitize_callback' => 'sanitize_text_field', 'auth_callback' => function() { return current_user_can('edit_posts'); } ));
add_action('init', 'myprefix_register_meta');

Now try the following:

  • Open a new post in WordPress.
  • Run this in the DevTools console see the current value of the field:'core/editor').getEditedPostAttribute('meta')
  • Run this in DevTools to update the value:'core/editor').editPost({meta: {_myprefix_text_metafield: 'new value'}})
  • There will be errors, so save the post to clear them.
  • Refresh the page and run this in the DevTools console:'core/editor').getEditedPostAttribute('meta')

Does the new value show up in the console? If so, great! Now we know how to get and set the meta field value using Redux and we are ready to create a react component in the sidebar to do that.

Creating a React component to manage the custom fields

What we need to do next is create a React component that contains a text field that is controlled by the value of the metafield in the Redux store. It should have the value of the meta field…and hey, we already know how to get that! We can create the component in a separate file and then import it index.js. However I am simply going to create directly in index.js since we’re dealing with a very small example.

Again, we’re only working with a single text field, so let’s import a component provided by a WordPress package called @wordpress/components. This package contains a lot of reusable components that are Gutenberg-ready without us having to write them from scratch. It’s a good idea to use components from this package in order to be consistent with the rest of the Gutenberg UI.

First, let’s install this package:

npm install --save @wordpress/components

We’ll import TextControl and PanelBody at the top of index.js to fetch the two components we need from the package:

import { PanelBody, TextControl } from "@wordpress/components";

Now let’s create our component. I am going to create a React functional component and call it PluginMetaFields, but you can use a class component if you’d prefer that.

let PluginMetaFields = (props) => { return ( <> <PanelBody title={__("Meta Fields Panel", "textdomain")} icon="admin-post" intialOpen={ true } > <TextControl value={'core/editor').getEditedPostAttribute('meta')['_myprefix_text_metafield']} label={__("Text Meta", "textdomain")} /> </PanelBody> </> )

PanelBody takes title, icon and initialOpen props. Title and icon are pretty self-explanatory. initialOpen puts the panel in an open/expanded state by default. Inside the panel, we have TextControl. which receives a label and a value for the input. As you can see in the snippet above, we get the value from the global store by accessing the _myprefix_text_metafield field from the object returned by'core/editor').getEditedPostAttribute('meta').

Notice that we are now depending on @wordpress/components and use We must add these packages as dependencies when we enqueue our file in plugin.php:

function myprefix_enqueue_assets() {
wp_enqueue_script( 'myprefix-gutenberg-sidebar', plugins_url( 'build/index.js', __FILE__ ), array( 'wp-plugins', 'wp-edit-post', 'wp-element', 'wp-components', 'wp-data' ) );
add_action( 'enqueue_block_editor_assets', 'myprefix_enqueue_assets' );

Let’s officially add the component to the sidebar instead of the dummy text we put in earlier as a quick example:

registerPlugin( 'myprefix-sidebar', { icon: 'smiley', render: () => { return ( <> <PluginSidebarMoreMenuItem target="myprefix-sidebar" > {__('Meta Options', 'textdomain')} </PluginSidebarMoreMenuItem> <PluginSidebar name="myprefix-sidebar" title={__('Meta Options', 'textdomain')} > <PluginMetaFields /> </PluginSidebar> </> ) }

This should should give you a “Meta Options” panel that contains a “Meta Fields” title, a pin icon, and a text input with a “Test Meta” label and default value of “new value.”

Nothing will happen when you type into the text input because we are not yet handling updating the field. We’ll do that next, however, we first need to take care of another problem. Try to run editPost in the DevTools console again, but with a new value:'core/editor').editPost({meta: {_myprefix_text_metafield: 'a newer value'}})

You will notice that the value in the text field will not update to the new value. That’s the problem. We need the field to be controlled by the value in the Redux store, but we don’t see that reflected in the component. What’s up with that?

If you have used Redux with React before, then you probably know that we need to use a higher order component called connect in order to use Redux store values in a React component. The same goes for React components in Gutenberg — we have to use some higher order component to connect our component with the Redux-like store. Unfortunately, we are unable to simply call directly as we did before. This higher order component lives in the global variable which is also available as an npm package called So let’s install it to help us solve the issue.

npm install --save @wordpress/data

The higher order component we need is called withSelect, so let’s import it in index.js.

import { withSelect } from "@wordpress/data";

Remember that we already added wp-data as a dependency in wp_enqueue_script, so we can just use it by wrapping our component with it, like so:

PluginMetaFields = withSelect( (select) => { return { text_metafield: select('core/editor').getEditedPostAttribute('meta')['_myprefix_text_metafield'] } }

Here, we’re overriding our PluginMetaFields component and assigning it the same component, now wrapped with the withSelect higher order component. withSelect will receive a function as an argument. This function will receive the select function (which we used to access and it should return an object. Each key in this object will be injected as a prop in the component (similar to connect in Redux). withSelect will return a function that we can pass it the component (PluginMetaFields) again as seen above. So, by having this higher order component, we now get text_metafield as a prop in the component, and whenever the meta value in the redux store is updated, the prop will also get updated — thus, the component will update since components update whenever a prop is changed.

let PluginMetaFields = (props) => { return ( <> <PanelBody title={__("Meta Fields Panel", "textdomain")} icon="admin-post" intialOpen={ true } > <TextControl value={props.text_metafield} label={__("Text Meta", "textdomain")} /> </PanelBody> </> )

If you now try and run editPost with a new meta value in your browser, the value of the text field in the sidebar should also be updated accordingly!

So far, so good. Now we know how to connect our React components with our Redux-like stores. We are now left with updating the meta value in the store whenever we type in the text field.

Dispatching actions in React components

We now need to dispatch the editPost action whenever we type into the text field. Similar to, we also should not call directly in our component like so:

// Do not do this
<TextControl value={props.text_metafield} label={__("Text Meta", "textdomain")} onChange={(value) =>'core/editor').editPost({meta: {_myprefix_text_metafield: value}}) }

We will instead wrap our component with another higher order component from the package called withDispatch. We’ve gotta import that, again, in plugin.js:

import { withSelect, withDispatch } from "@wordpress/data";

In order to use it, we can wrap our component — which is already wrapped with withSelect and again with withDispatch — like so:

PluginMetaFields = withDispatch( (dispatch) => { return { onMetaFieldChange: (value) => { dispatch('core/editor').editPost({meta: {_myprefix_text_metafield: value}}) } } }

You can check out yet another WordPress package called @wordpress/compose. It makes using multiple high order components a bit cleaner for use in a single component. But I will leave that to you to try out for the sake of keeping our example simple.

withDispatch is similar to withSelect in that it will receive a function that has the dispatch function as an argument. That allows us to return an object from this function that contains functions that will be available inside the component’s props. I went about this by creating a function with an arbitrary name (onMetaFieldChange) that will receive a value, dispatch the editPost action, and set the meta value in the Redux store to the value received in the function’s argument. We can call this function in the component and pass it the value of the text field inside the onChange callback:

<TextControl value={props.text_metafield} label={__("Text Meta", "textdomain")} onChange={(value) => props.onMetaFieldChange(value)}

Confirm everything is working fine by opening the custom sidebar in the WordPress post editor, updating the field, saving the post and then refreshing the page to make sure the value is saved in the database!

Let’s add a color picker

It should be clear now that can we update a meta field using JavaScript, but we’ve only looked at simple text field so far. The @wordpress/components library provides a lot of very useful components, including dropdowns, checkboxes, radio buttons, and so on. Let’s level up and conclude this tutorial by taking a look at how we can use the color picker component that’s included in the library.

You probably know what to do. First, we, import this component in index.js:

import { PanelBody, TextControl, ColorPicker } from "@wordpress/components";

Now, instead of registering a new custom field, let’s aim for simplicity and assume that this color picker will be controlled by the same _myprefix_text_metafield field we worked with earlier. We can use the ColorPicker component inside our PanelBody and it will be very similar to what we saw with TextControl, but the prop names will be slightly different. We have a color prop instead of value and onChangeComplete instead on onChange. Also, onChangeComplete will receive a color object that contains some information about the chosen color. This object will have a hex property we can use to store the color value in the _myprefix_text_metafield field.

Catch all that? It boils down to this:

<ColorPicker color={props.text_metafield} label={__("Colour Meta", "textdomain")} onChangeComplete={(color) => props.onMetaFieldChange(color.hex)}

We should now have a color picker in our sidebar, and since it’s controlling the same meta field as the TextControl component, our old text field should update whenever we pick a new color.

That’s a wrap!

If you have reached this far in the article, then congratulations! I hope you enjoyed it. Make sure to check out my course if you want to learn more about Gutenberg and custom blocks. You can also find the final code for this article over at GitHub.

The post Managing WordPress Metadata in Gutenberg Using a Sidebar Plugin appeared first on CSS-Tricks.

JAMstack Fundamentals: What, What And How

JAMstack Fundamentals: What, What And How

JAMstack Fundamentals: What, What And How

Vitaly Friedman

We love pushing the boundaries on the web, and so we’ve decided to try something new. You probably have heard of JAMstack — the new web stack based on JavaScript, APIs, and Markup — but what does it mean for your workflow and when does it make sense in your projects?

As a part of our Smashing Membership, we run Smashing TV, a series of live webinars, every week. No fluff — just practical, actionable webinars with a live Q&A, run by well-respected practitioners from the industry. Indeed, the Smashing TV schedule looks pretty dense already, and it’s free for Smashing Members, along with recordings — obviously.

We’ve kindly asked Phil Hawksworth to run a webinar explaining what JAMStack actually means and when it makes sense, as well as how it affects tooling and front-end architecture. The one hour-long webinar is now available as well. We couldn’t be happier to welcome Phil to co-MC our upcoming SmashingConf Toronto (June 25-26) and run JAMStack_conf London, which we co-organize on July 9-10 this year as well. So, let’s get into it!

Phil Hawksworth: Excellent, okay, well let’s get into it then. Just by way of a very quick hello, I mean I’ve said hello already, Scott’s given me a nice introduction. But yes, I currently work at Netlify, I work in the developer experience team there. We are hopefully going to have plenty of time for Q&A but, as Scott mentioned, if you don’t get a chance to ask questions there, or if you just rather, you can ping them directly at me on Twitter, so my Twitter handle is my names, it’s Phil Hawksworth, so any time you can certainly ask me questions about JAMstack or indeed anything on Twitter.

Phil Hawksworth: But I want to start today just by kind of going back in time a little bit to this quote which really resonates very, very strongly with me. This is a quote from the wonderful Aaron Schwartz who, of course, contributed so much to the Creative Commons and the open web and he wrote this on his blog way back in 2002, and he said, “I care about not having to maintain cranky AOL server, Postgres and Oracle installs.” AOL server, I had to look up to remind myself was an open source web server at the time.

Phil Hawksworth: But this chimes really strongly with me. I also don’t want to be maintaining infrastructure to keep a blog alive, and that’s what he was talking about. And it was in this blog post on his own blog and it was titled “Bake, Don’t Fry”. He was picking on a term that someone who’d built a CMS recently had started to use, and he kind of popularized this term about baking (Bake, Don’t Fry); what he’s talking about there is pre-rendering rather than rendering on demand, so baking the content ahead of time, rather than frying it on demand when people come and ask for it — getting things away from request time and into kind of build time.

Phil Hawksworth: And when we’re talking about pre-rendering and rendering, what we mean by that is we’re talking about generating markup. I feel a bit self-conscious sometimes talking about kind of server render or isomorphic rendering or lots of these kind of buzzwordy terms; I got called out a few years ago at a conference, Frontiers Conference in Amsterdam when I was talking about rendering on the server and someone said to me, “You mean generating HTML? Just something that outputs HTML?” And that’s, of course, what I mean.

Phil Hawksworth: But all of this kind of goes a long way towards simplifying the stack. When we think about the stack that we serve websites from; I’m all about trying to simplify things, I’m super keen on trying to simplify the stack. And that’s kind of at heart of this thing called “JAMstack” and I want to try and explain this a little bit. The “JAM” in JAMstack stands for JavaScript, APIs and Markup. But that’s not enough really to help us understand what it means — what on earth does that really mean?

Phil Hawksworth: Well, what I want to try and do in the next half hour or so, is I want to kind of expand on that definition and give more of a description of what JAMstack is. I want to talk a bit about the impact and the implications of JAMstack, and, you know, think about what that can give us as to why we might choose it. Along the way, I’m going to try to mention some of the tools and services that will be useful, and hopefully, I’ll wrap up with some resources that you might want to dig into and perhaps mention some first steps to get you under way.

Phil Hawksworth: So, that’s the plan for the next half-hour. But, I want to, kind of, come back to this notion about simplifying the stack, because, hopefully, people who join this or have come to watch this video later on, maybe you’ve got a notion of what JAMstack is, or maybe it’s a completely new term, and you’re just curious. But, ultimately, there are a lot of stacks out there, already. There are lots of ways that you can deliver a website. It feels like we’ve been building different types of infrastructure for a really long time, whether that’s a LAMP stack or the MAMP stack, or the — I don’t know — the MEAN stack. There’s a bunch of them floating by on the screen here. There are lots and lots of them.

Phil Hawksworth: So, why on earth would we need another one? Well, JAMstack is, as I mentioned, is JavaScript/API/Markup, but if we try and be a tiny bit more descriptive, JAMstack is intended to be a modern architecture, to help create fast and secure sites and dynamic apps with JavaScript/APIs and pre-rendered markup, served without web servers, and it’s this last point which is, kind of, something that sets it apart and maybe, makes it a little bit more, kind of, interesting and unusual.

Phil Hawksworth: This notion of serving something without web servers, that sounds either magical or ridiculous, and hopefully, we’ll figure out what along the way. But to try and shed some light over this and describe it in a little bit more detail, it’s sometimes useful to compare it to what we might think of as a traditional stack, or a traditional way of serving things on the web. So, let’s do that just for a second. Let’s just walkthrough, perhaps, what a request might look like as it gets serviced in a traditional stack.

Phil Hawksworth: So, in this scenario, we got someone opening up a web browser and making a request to see a page. And maybe that request hits a CDN, but probably, more likely, it hit some other infrastructure that we are hosting — as the people who own this site. Maybe we tried to make sure that this is going to scale under lots of load because we, obviously, want a very popular and successful sight. So, perhaps we got a load balancer, that has some logic in it, which will service that request to one of a number of web servers that we’ve provisioned and configured and deployed to. There might be a number of those servers.

Phil Hawksworth: And those servers will execute some logic to say, “Okay, here’s our template, we need to populate that with some data.” We might get our data from one of a number of database servers that will perform some logic to look up some data, return that to the web server, create a view that we then pass back through the load balancer. Perhaps, along the way, calling off to CDN, stashing some assets in the CDN, and I should clarify, a CDN is a Content Delivery Network, so a network of machines distributed around the Internet to try and get request service as close to possible to the user and add things, like caching.

Phil Hawksworth: So, we might stash some assets there, and ultimately, return a view into the browser, into the eyeballs of the user, who gets to then experience the site that we built. So, obviously, that’s, either, an oversimplification or a very general view of how we might service a request in a traditional stack. If we compare that to the JAMstack, which is servicing things in a slightly different way, this is how it might look.

Phil Hawksworth: So, again, same scenario, we’re starting in a web browser. We’re making a request for a view of the page, and that page is already in a CDN. It serves statically from there, so it’s returned to the user, into the browser, and we’re done. So, obviously, a very simplified view, but straight away, you can start to see the differences here in terms of complexity. In terms of places that we need to manage code, deeply code, all of those different things. So, for me, one of the core attributes one of a JAMstack, is that it means that you’re building a site that’s capable of being served directly from a CDN, or even from a static file server. CDN is something that we might want to put in place to handle load, but ultimately, this could be served directly from any kind of static file server, kind of static hosting infrastructure.

Phil Hawksworth: JAMstack, kind of, offers an opportunity to reduce complexity. Just comparing those two parts of the diagram that we’ll come back to a few times, over the course of the next half hour, you can see that it’s an opportunity to reduce complexity and reduce risk. And so, it means that we can start to enjoy some of the benefits of serving static assets, and I’m going to talk about what those are a little bit later on. But you might be looking at this and thinking, “Well, great, but isn’t this just the new name for static websites?” That’s a reasonable thing to level at me when I’m saying, “We’re going to serve things statically.”

Phil Hawksworth: But I want to come back to that. I want to talk about that a little bit more, but first of all, I want to, kind of, talk about this notion of stacks and what on earth is a stack, anyway? And I think of a stack as the layers of technology, which deliver your website or application. And we’re not talking about the build pipeline, or the development process, but certainly the way we serve sites can have a big impact on how we develop and how we deploy things, and so on.

Phil Hawksworth: But here, we’re talking about the technology stack, the layers of technology, that actually deliver your website and your application to the users. So, let’s do another little comparison. Let’s talk about the LAMP stack for a second.

Phil Hawksworth: The LAMP stack, you may remember, is made up of an apache web server, for doing things like the HCP routing and the serving of static assets. PHP, for some pre-processing, so pretty hyper-text processing; applying the logic, maybe building the views for the templates and what have you. And has some access to your data, by my NISQL, and then LINUX is the operating system that sits beneath all of that, keeps that all breathing. We can wrap that up together notionally as this web server. And we may have many of these servers, kind of, sitting together to serve a website.

Phil Hawksworth: That’s a, kind of, traditional look at the LAMP stack, and if we compare that to the JAMstack, well, here, there’s a critical change. Here, we’re actually moving up level, rather than thinking about the operating system and thinking about how we run the logic to deliver a website. Here we’re making an assumption that we’re going to be serving these things statically. So, we’re doing the ACP routing, and the serving of assets from a static server. That can be reasonably done. We got very good at this, over the years, building ways to deliver static websites, or static assets.

Phil Hawksworth: This might be a CDN, and again, we’ll talk about that in a moment. But the area of interest for us, is happening more in the browser. So, here, this is where our markup is delivered and is parsed. This is where JavaScript can execute, and this is happening in the browser. In many ways, the browser has become the runtime for the modern web. Rather than having the runtime in the server infrastructure, itself, now we’ve moved that up a level, closer to the user, and into the browser.

Phil Hawksworth: When it comes to accessing data, well, that’s happening through, possibly, external APIs, making calls via JavaScripts to these external APIs to get server access, or we can think APIs as the browser APIs, being able to interact with JavaScript with capabilities right there in your browser.

Phil Hawksworth: Either way, the key here about the JAMstack is that, we’re talking about things that are pre-rendered: they’re served statically and then, they maybe progressively enhanced in the browser to make use of browser APIs, JavaScripts, and what have you.

Phil Hawksworth: So, let’s just do this little side-by-side comparison here. Again, I just want to kind of reiterate that the JAMstack has moved up a level to the browser. And if we see the two sides of this diagram, with the LAMP stack on the left and effectively, the JAMstack on the right, you might even think that, well, even when we were building things with the LAMP stack, we’re still outputting mark-up. We’re still outputting JavaScript. We might still be accessing APIs. So, in many ways, the JAMstack is almost like a subset of what we were building before.

Phil Hawksworth: I used to sometimes talk about JAMstack as the assured stack, because it’s assures a set of tools and technologies that we need to deliver a site. But, either way, it’s a much simplified way of delivering a site that, kind of, does away with the need for things to execute and perform logic at the server at request time.

Phil Hawksworth: So, this can do a lot of things. This can, kind of, simplify deployments and again, I’m going to call back to this diagram from time-to-time. If we think about how we deploy our code and our site, for every deploy, from the very first one, through the whole development lifecycle, all the way through the life of the website. On the traditional stack, we might be having to change the logic and the content for every box on that diagram.

Phil Hawksworth: Whereas, in the JAMstack, when we’re talking about deploying, we’re talking at getting things to the CDN, getting things to the static server, and that’s what the deployment entails. The build, the kind of logic that runs the build — that can run anywhere. That doesn’t need to run in the same environment that’s hosting the web server. In fact, it doesn’t! It starts the key to the JAMstack. We put the separation at what happens at request time, serving these static assets, versus what happens at build time, which can be your logic that you run to build and then to the deployment.

Phil Hawksworth: So, this kind of decoupling is a key thing, and I’m going to come back to that later on. We’ve got very good at serving static files, and getting things to a CDN or getting things to the file system (the file server) is somewhere that we’ve seen huge, kind of, advancement over the last few years. There are a lot of tools and processes, now, that can help us do this really well. Just to call out a few services that can serve static assets well and give workflows to getting your build to that environment, they’re the usual suspects that you might imagine the big clouds infrastructure providers, like Azure, AWS, and Google Cloud.

Phil Hawksworth: But then, there are others. So, the top one on the right is a service called Surge, which has been around for a few years. It allows you to run a command in your build environment and deploy your assets through to their hosting environment. Netlify, the next one down, is where I work and we do very much the same thing but we have different automation as well. I could go into it another time. And the one on the bottom, another static hosting environment site, called Now.

Phil Hawksworth: So, there’s a bunch of different options for doing this, and all of these spaces provide different tooling for getting to the CDN, as quickly as possible. Getting your sites deployed in the most seamless way that we can. And they all have something in common where they’re building on the principal of running something locally. I often think of a static site generator as something that we might run in a build which when we run that, it takes things like content and templates and maybe, data from different services and it outputs something which can be served statically.

Phil Hawksworth: We can preview that locally in our static server. Something that is kind of simple to do on any local development environment, and then the process of deploying that is getting that to the hosting environment and ideally, out to a CDN in order to get, kind of, scale. So, with that kind of foundation laid out, I want to address a bit of a common misconception when it comes to JAMstack sites. And I didn’t do myself any favors by opening this up as describing JAMstack sites as being JavaScript, APIs, and Markup. Because the common misconception is that every JAMstack site has to be JavaScript and APIs, and Markup, but this kind of thing that we’ve overlooked is that we don’t have to use all three — every one one of these is, kind of, optional. We can use as much, or as little of these as we like. In the same way that a LAMP stack site wouldn’t necessarily need to be hitting a data base. Now, I’ve built things in the past that are served by an apache server, on a Linux machine, and I’ve been using PHP, but I haven’t been hitting a database and I wouldn’t start to rename a stack necessarily for that.

Phil Hawksworth: So, if we think about what is a JAMstack site, then it could be a bunch of different things. It might be something that’s built out with a static site generator, like Jekyll, pulling content from YAML files to build a site that has no JavaScript, doesn’t hit APIs at all, and we serve it on something, like GitHub Pages. Or, that would be a JAMstack site. Or maybe we’re using a static site generator, like Gatsby, which is, rather in a Ruby environment for Jekyll, now this is a JavaScript static site generator built in the React ecosystem.

Phil Hawksworth: That might be pulling content again, and it’s organizing Markdown files. It might be enriching that with calls to APIs, GraphQL’s APIs. It might be doing things in the browser, like doing JavaScript hydration of populating templates right there in the browser. And it might be served on Amazon S3. Is that a JAMStack site? Yeah, absolutely!

Phil Hawksworth: Moving on to a different static site generator, Hugo, which is built with Go! Again, we might be organizing content in Markdown files, adding interactions in the browser using JavaScript. Maybe not calling any external APIs and maybe hosting that on Google Cloud. Is it JAMstack? Absolutely! You see, I’m building to a theme here. Using something like Nuxt, another static site generator, now built in the View ecosystem. Maybe that’s pulling content from different adjacent files? Again, we might be using JavaScript interactions in the browser, perhaps calling APIs to do things like e-Commerce, serving it another static site. Another hosting infrastructure like Netlify, is it a JAMstack? Yes, it is!

Phil Hawksworth: But we might even go, you know, go off to this side end of the scale, as well. And think about a handmade, progressive web app that we’ve built artisanally, hand-rolled, JavaScript that we built ourselves. We’re packaging it up with webpack. We’re maybe using JavaScript web tokens and calling out to APIs to do authentication, interacting with different browser APIs, hosting it on Azure. Yes, that’s JAMstack as well!

Phil Hawksworth: And, you know, all of these things, and many more, can be considered JAMstack, because they all share one attribute in common and that is none of them are served with an origin server. None of them have to hit a server that performs logic at request time. These are being served as static assets, and then enriched with JavaScript and calls to APIs, afterwards.

Phil Hawksworth: So, again, I just want to reiterate that a JAMstack means it’s capable of being served directly from the CDN. So, I want to just call out some of the impacts and implications of this, because why would we want to do this? Well, the first notion is about security, and we’ve got a greatly reduced surface area for attack, here. If we think about (coming back to this old diagram again), the places where we might have to deal with an attack, we have to secure things like the load balancer, the webservers, the database servers. All of these things, we have to make sure aren’t able to be penetrated by any kind of an attack and, indeed, the CDN.

Phil Hawksworth: If the more pieces we can take out of this puzzle, the fewer places that can be attacked and the fewer places we have to secure. Having few moving parts to attack is really very valuable. At Netlify, we operate our own CDNs, so we get the luxury of being able to monitor the traffic that comes across it, and even though all of the sites hosted on Netlify, all of the JAMstack sites that you might imagine, none of them have a WordPress admin page on them because it’s completely decoupled. There is no WordPress admin, but we see a huge volume of traffic, probing for things like WP Admin, looking for ways in, looking for attack vectors.

Phil Hawksworth: I really love some of the things that Kent C. Dodds has done. I don’t know if you are familiar with the React community, you’ve probably encountered Kent C. Dodds in the past. He doesn’t use WordPress, but he still routes this URL, the WPAdmin. I think he used to route it through to a Rick Roll video on YouTube. He’s certainly been trolling people who have gone probing for it. But, the point is, by decoupling things in that way and, kind of, moving things that happen, build time from what happens in request time, we can just drastically reduce our exposure. We’ve got no moving parts at request time. The moving parts are all completely decoupled at build time. Potentially, on completely, well, necessarily on completely different infrastructure.

Phil Hawksworth: This, of course, also has an impact on performance, as well. Going back to our old friend here, the places we might want to try and improve performance across the stack here, when there’s logic that needs to be executed at these different places. The way that this often happens in traditional stacks is, they start to add layers, add static layers, in order to improve performance. So, in other words, try and find ways that we can start to behave as if it’s static. Not have to perform that logic at each level of the stack in order to speed things up. So, we’re starting to introduce things like caching all over the infrastructure and obvious places we might find to do that is in the web server, rather than perform that logic, we want to serve something immediately without performing that logic.

Phil Hawksworth: So, it’s kind of like a step towards, kind of, being pseudo-static. Likewise in database servers, we want to add caching layers to cache-com queries. Even in the low balance, the whole CDN, you can think of as a cache. But on the traditional stack, we need to figure out how to manage that cache, because not everything will be cached. So, there’s going to some logic about. What needs to be dynamically populated versus what can be cached. And the JAMstack model, everything is cached. Everything is cached from the point that the deployment is done, so we can think about it completely differently.

Phil Hawksworth: This, then, starts to, kind of, hint through to scaling, as well. And by scale, I’m talking about, how do we handle large loads of traffic? Traditional stacks will start to add infrastructure in order to scale. So, yes, to caching. We’re starting to put in place in our traditional stack. That will help — to a degree. What typically happens is, in order to handle large loads of traffic, we’ll start expanding the infrastructure and starting to add more servers, more pieces to handle these requests, costing these things out and estimating the load is a big overhead and it can be a headache for anyone doing technical architecture. It certainly was for me, which is why I was starting to lean much more towards doing the JAMstack approach where I just know that everything is served from the CDN, which is designed by default to handle scale, to handle performance right out of the gate.

Phil Hawksworth: So, I also want to give a nod to developer experience, and the impact this can have there. Now, developer experience should never be seen as something which trumps user experience, but I believe that a good developer experience can reduce friction, can allow for developers to do a much better job of building up to great user experiences!

Phil Hawksworth: So, when we think about where the developer experience lives, and where the areas of concern for a developer are here: well, in a traditional stack, we might need to think about how we get the code to all of these different parts of the infrastructure, and how they all play together. In the JAMstack world, really, what we’re talking about is this box here at the bottom. You know, how do we ran the build and them, how do we automate a deployment to get something served in the first place? And the nice thing is, that in the JAMstack model, what you do in that build is completely up to you.

Phil Hawksworth: That’s a really well-defined problem space, because ultimately, you’re trying to build something you can serve directly from a CDN. You want to pre-render something, using whatever tools you like: whether it’s a static site generator built in Ruby or Python or JavaScript or Go or PHP, you have the freedom to make that choice. And so, that can create a much nicer environment for you to work in. And also, it creates an opportunity to have real developer confidence because a real attribute of JAMstack sites is that they can be much more easily served as immutable and atomic deployment.

Phil Hawksworth: And I want to, kind of, jump away from the slides just for a moment, to describe what that means, because an immutable deployment and an atomic deployment can… (that can just sound a little bit like marketing speak) but what I’m going to do, is I’m going to jump into my browser. Now … actually, I’m going to go back for a second. Let me… just do this.

Phil Hawksworth: Here we are. This will be easier. Jumping right into the page. Now, Scott, you will tell me, Scott, if you can’t see my browser, I’m hoping. Now, assuming everyone can see my browser.

Scott: Everything looks good.

Phil Hawksworth: Excellent! Thank you very much!

Phil Hawksworth: So, what I’m doing here, is I’m using Netlify as an example, as an example of the service. But, this is an attribute which is common to sites that can be hosted, statically. So, when we talk about an immutable deployment, what we mean is, that rather each deployment of code having to touch lots of different parts of the infrastructure, and change lots of things, here we’re not mutating the state of the site on the server. We’re creating an entirely new instance of the site for every deployment that’s happened. And we can do that because the site is a collection of static assets.

Phil Hawksworth: Here, I’m looking at the deployment that have happened from my own website. I’ll give you a treat. There you are, that’s what it looks like. It’s just a blog, it doesn’t look like anything particularly remarkable or exciting. It’s a statically generated blog, but what I have here is every deployment that’s ever happened, lives on in perpetuity, because it’s a collection of static assets that are served from a CDN. Now, I could go back as far as my history can carry me and go and look at the site, as it was back in… when was this? This was August, 2016. And by virtue of it being a set of static assets, we’re able to host this on its own URL that lives on in perpetuity and if I even wanted to, I could decide to go in and publish that deployment.

Phil Hawksworth: So, now, anyone’s who’s looking at my website, if I go back to my website here, if I refresh that page, now that’s being served directly from the CDN with the assets that were there before. Now, I can navigate around again. Here, you can see. Look, I was banging on about this, I was using these terrible terms like isomorphic rendering and talking about the JAMstack back in 2016. So, this is now what’s being served live on my site. Again, because there are mutual deployments that just live on forever. I’m going to just put my own, kind of, peace of mind, I’m going to — is this the first page? Yeah. I’m going to go back to my latest deployment. I’ll have to shut again, and get me back into the real world. Let me just make sure this is okay.

Phil Hawksworth: Okay! Great! So, then now, this is back to serving my previous version, or my latest version of the site. I’ll hop back to keynote. So, this is possible because things are immutable and atomic. The atomic part of that means, again, that the deployment is completely contained. So, you never get the point where some of the assets are available on the web server, but some of them won’t. Only when everything is there in context and everything is there, complete, do we toggle the serving of the site to the new version. Again, this is the kind of thing you can do much more easily if you’re building things out as a JAMstack site that serves directly from the CDN as a bunch of assets.

Phil Hawksworth: I noticed that my timer has reset, after going back and forward from keynote, so I think I have about six or seven minutes left. Tell me, Scott, if—

Scott: So, yeah, we’re still good for about ten minutes.

Phil Hawksworth: Ten minutes? Okay, wonderful!

Scott: There’s no rush.

Phil Hawksworth: Thank you, that should be good!

Phil Hawksworth: So, just switching gear a tiny bit and talking about APIs and services (since APIs is part of JAMstack), the kind of services that we then might be able to use is mostly JAMstack. You know, we might be using services that we built in-house, or we might be using bought-services. There are lots of different providers who can do things for us, and that’s because that’s their expertise. Through APIs, we might be pulling in content from content management systems as a service, and there’s a bunch of different providers for this, who specialize in giving a great content management experience and then, exposing the content through API, so you used to be able to pull them in.

Phil Hawksworth: Likewise, there are different ways that you can serve assets. People like Cloudary are great at this, for doing image optimization, serving assets directly to your sites, again, through APIs. Or what about e-Commerce? You know, there are places like Stripe or Snipcart that can provide us API, so that we don’t have to build these services ourselves and get into the very complex issues that come with trying to build an e-Commerce engine. Likewise, identity, from people like Auth0 who are using Oauth. There are lots of services that are available and we can consume these things through APIs, either in the browser or at build time, or sometimes, a combination of both.

Phil Hawksworth: Now, some people might think, “Well, that’s fine, but I don’t want to give the keys to the kingdom away. I don’t want to risk giving these services over to external providers,” and to that, I say, well, you know, vendors who provide a single service really depend on its success. If there’s a company that’s core business, or entire business, is in building-out an e-Commerce engine, an e-Commerce service for you, they’re doing that for all of their clients, all of their customers, so they really depend on its success and they have the specialist skills to do that.

Phil Hawksworth: So, that kind of de-risks it from you a great deal. Especially when you start to factor in the fact that you can have your technical and service-level contracts to give you that extra security. But it’s not all about bought services, it’s also about services you can build yourselves. Now, there’s a number of ways that this can happen, but sometimes, you absolutely need a little bit of logic on the server. And so far, I’ve just been talking about taking the server out of the equation. So, how do we do that?

Phil Hawksworth: Well, this is where serverless can really come to the rescue. Serverless and JAMstack, they just fit together really beautifully. And when I’m talking about serverless, I’m talking about no functions as a service. I know that serverless can be a bit of a loaded term, but here, I’m talking about functions as a service. Because functions as a service can start to enable a real micro-services architecture. Using things like AWS Lambda or Google Cloud functions or similar functions as a service, can allow you to build out server infrastructure without a server. Now, you can start deploying JavaScript logic to something that just runs on demand.

Phil Hawksworth: And that means, you can start supplementing some of these other services with, maybe, very targeted small services you build yourselves that can run the serverless functions. These kind of smaller services are easier to reason about, understand, build out and they create much greater agility. I want to just mention a few examples and results from JAMstack sites. I’m not going to go down the server list avenue too much, right now. We can, maybe, come back to that in the questions. I really just kind of want to switch gear and, thinking about time a little bit, talk about some examples and results.

Phil Hawksworth: Because there are some types of sites that lend themselves in a very obvious way to a JAMstack site. Things like the documentation for React, or Vuejs, those [inaudible 00:32:40], pre-rendered JAMstacks sites. As do sites for large companies, such as Citrix, this is a great example of Citrix multi-language documentation. You can actually view the video from the JAMstack conference that happened in New York, where Beth Pollock had worked on this project, talked about the change that went on in that project. From building on traditional, non-enterprised infrastructure to a JAMstack approach and building with Jekyll, which is not necessarily the fastest generating static site generator, but still, they saw a huge improvement.

Phil Hawksworth: Beth talked about the turnaround time for updates went from weeks to minutes. Maybe people are kind of frowning at the idea of weeks for updates to sites, but sometimes in big complex infrastructure, with lots of stakeholders and lots of moving parts, this really is the situation we’re often finding ourselves in. Beth also talked about estimating the annual cost savings for this move to a JAMstack site. To get the site running properly, estimated their savings of around 65%. That’s huge kind of savings. Changing gear to a slightly different type of site, something a little closer to home, Smashing Magazine itself is a JAMstack site, which might be a little bit surprising, because on one hand, yes, there’s lots of articles and it’s also content, which is published regularly, but not every minute of the day, for sure.

Phil Hawksworth: So, that might lend itself, perhaps, for something that’s pre-generated, but of course, there’s also a membership area and an event section, and a job board, and e-Commerce, and all of these things. This is all possible on the JAMstack because not only are we pre-rendering, but we’re also enriching things with JavaScript and the front end to call out to APIs, which let some of these things happen. The project that I think I saw Vitaly arrive in the call, so that’s going to be good, we might be able to come back to this in a few minutes.

Phil Hawksworth: But the project that migrated, Smashing Magazine onto a JAMstack approach, I believe, simplified the number of platforms from five, effectively down to one. And I’m using Vitaly’s words directly here: Vitaly talked about having some caching issues, trying to make the site go quickly, using probably every single WordPress caching plug-in out there, and goodness knows, there are a few of them! So, Smashing Magazine saw an improvement in performance, time to first load went from 800 milliseconds to 80 milliseconds. Again, I’m simplifying the infrastructure that served the site up in the first place. So, it’s kind of interesting to see the performance gains that can happen there.

Phil Hawksworth: Another totally different type of site. This is from the Google Chrome team, who built this out to demonstrate at Google I/O this year. This very much feels like an application. This is Minesweeper in a browser. I apologize if you’re watching me play this. I’m not playing it while talking to you; I recorded this sometime ago and it’s agony to see how terrible I seem to be at Minesweeper while trying to record. That’s not a mine, that can’t be!

Phil Hawksworth: Anyway, we’ll move on.

Phil Hawksworth: The point of that is, this is something that feels very much more like an app, and it was built in a way to be very responsible about the way it used JavaScript. The payload to interactive was 25KB. This progressively would download and use other resources along the way, but it meant that the time to interact was under five seconds on a very slow 3G network. So, you can be very responsible with the way you use JavaScript and still package up JavaScript, as part of the experience for a JAMstack site.

Phil Hawksworth: So, I’m kind of mindful of time. We’re almost out of time, so what is the JAMstack? Well, it’s kind of where we started from. JAMstack sites are rendered in advance: they’re not dependent on an origin server (that’s kind of key), and they may be progressively enhanced in the browser with JavaScript. But as we’ve shown, you don’t have to use JavaScript at all. You might just be serving that statically, ready to go, without that. It’s an option available to you.

Phil Hawksworth: This key tenant, I think of, JAMstack sites is they’re served without web service. They’re pre-rendered and done in advance.

Phil Hawksworth: If you’re interested in more, it’s already been mentioned a little bit, there is a conference in London in July — July 9th and 10th. The speakers are going to be talking about all kinds of things to do with performance in the browser, things that you can do in the browser, results of building on the JAMstack and things to do with serverless.

Phil Hawksworth: There’s also a bunch of links in this deck that I will share, after this presentation, including various bits and pieces to do with static site generation, things like headless CMS, the site itself, and a great set of resources on a website called “The New Dynamic” which is just always full of latest information on JAMstack. We’re out of time, so I’ll wrap it up there, and then head back across to questions. So, thanks very much for joining and I’d love to take questions.

Scott: Thanks, Phil. That was amazing, thank you. You made me feel quite old when you pulled up the Minesweeper reference, so—

Phil Hawksworth: (laughs) Yeah, I can’t take any credit for that, but it’s kind of fascinating to see that as well.

Scott: So, I do think Vitaly is here.

Vitaly: Yes, always in the back.

Phil Hawksworth: I see Vitaly’s smiling face.

Vitaly: Hello everyone!

Phil Hawksworth: So, I’m going to hand it over to Vitaly for the Q&A, because I seem to have a bit of a lag on my end, so I don’t want to hold you guys up. Vitaly, I’ll hand it over to you.

Scott: Okay. Thanks, Scott.

Vitaly: Thanks, Scott.

Vitaly: Hello—

Vitaly: Oh, no, I’m back. Hello everyone. Now Scott is back but Phil is gone.

Scott: I’m still here! Still waiting for everything.

Vitaly: Phil is talking. Aw, Phil, I’ve been missing you! I haven’t seen you, for what, for days, now? It’s like, “How unbelievable!” Phil, I have questions!

Vitaly: So, yeah. It’s been interesting for us, actually, to move from WordPress to JAMstack — it was quite a journey. It was quite a project, and the remaining moving parts and all. So, it was actually quite an undertaking. So, I’m wondering, though, what would you say, like if we look at the state of things and if we look in the complexes, itself, that applications have. Especially if you might deal with a lot of legacy, imagine you have to deal with five platforms, maybe seven platforms here, and different things. Maybe, you have an old legacy project in Ruby, you have something lying on PHP, and it’s all kind of connected, but in a hacky way. Right? It might seem like an incredible effort to move to JAMstack. So, what would be the first step?

Scott: So … I mean, I think you’re absolutely right, first of all. Re-platforming any site is a big effort, for sure. Particularly if there’s lots of legacy. Now, the thing that I think is kind of interesting is an approach that I’ve seen getting more popular, is in identifying attributes of the site, parts of the site, that might lend themself more immediately to being pre-generated and served statically than others. You don’t necessarily have to everything as a big bang. You don’t have to do the entire experience in one go. So, one of the examples I shared, kind of, briefly was the Citrix documentations site.

Scott: They didn’t migrate all of across to being JAMstack. They identified a particular part that made sense to be pre-rendered, and they built that part out. And then, what they did was they started to put routing in front of all the requests that would come into their infrastructure. So, it would say, “Okay, well, if it’s in this part of the past the domain, either in the sub-domain or maybe, through to a path, route that through something which is static, then the rest of it, pass that through to the rest of the infrastructure.

Scott: And I’ve seen that happen, time and time again, where with some intelligent redirects, which, thankfully, is something that you can do reasonably simply on the JAMstack. You can start to put fairly expressive redirect engines in front of the site. It means that you can pass things through just that section of the site that you tried to take on as a JAMstack project. So, choosing something and focusing on that first, rather than trying to do a big bang, where you do all of the legacy and migration in one. I think that’s key, because, yeah, trying to do everything at once is pretty tough.

Vitaly: It’s interesting, because just, I think, two days, maybe even today, Chris Coyier wrote an article renaming JAMstack to SHAMstack where, essentially, it’s all about JavaScript in which we need think about steady coasting, because JavaScript could be hosted steadily as well. And it’s interesting, because he was saying exactly that. He actually — when we think about JAMstack, very often, we kind of tend to stay in camps. It’s either, fully rendered and it lives a static-thing. Somewhere there, in a box and it’s served from a city and that’s it, or it’s fully-expressive and reactive and everything you ever wanted. And actually, he was really right about a few things, like identifying some of the things that you can off-load, to aesthetic-side, generated assets, so to say, to that area.

Vitaly: And, JAMstackify, if you might, say some of the fragments of your architecture. Well, that’s a new term, I’m just going to coin, right there! JAMstackify.

Phil Hawksworth: I’m going to register the domain quickly, before anybody else.

Phil Hawksworth: And it’s a nice approach. I think, it kind of makes my eye twitch a little bit when I hear that Chris Coyier has been redubbing it the SHAMstack, because it makes it sound like he thinks it’s a shambles. But I know that he’s really talking about static-hosting and markup, which I—

Vitaly: Yes, that’s right.

Phil Hawksworth: I really like, because the term JAMstack can be really misleading, because it’s trying to cover so many different things and the point I was trying to, I probably hammered it many times in that slide, is that it can be all kinds of things. It’s so broad, but the key is pre-rendering and hosting the core of the sites statically. It’s very easy for us to get into religious wars about where it needs to be a React site. It has to be a React app, in order to be a JAMstack site, or it’s a React app, so it can’t be JAMstack. But, really, the crux of it is, whether you use JavaScript or not, whether you’re calling APIs or not, if you pre-render and get things into a static host that can be very performant, that’s the core of JAMstack.

Vitaly: Yes, absolutely.

Phil Hawksworth: We’re very fortunate that browser’s are getting so much more capable, and the APIs that are there within browser’s themselves can allow us to do much more as well. So, that kind of opens the doors even further, but it doesn’t mean that everything that we build as a JAMstack site has to make use of everything. Depending on what we’re trying to deliver, that’s how we should start to choose the tools that we’re playing with to deploy those things.

Vitaly: Absolutely. We have Doran here. Doran, I think I know, Doran. I have a feeling that I know Doran. He’s asking, “Do you expect serverless to be gravitating towards seamless integration with JAMstack from [inaudible 00:44:36]? What is referred to as the A in JAM.

Phil Hawksworth: That’s a great question, because I think, serverless functions are — they just go so well with JAMstack sites, because in many ways, in fact, I think someone once asked me if JAMstack sites are serverless, and so I squirmed about that question, because serverless is such a loaded term. But, in many ways, it’s bang-on because I was talking, time and time again, about there’s no origin server. There’s no server infrastructure for you to manage. In fact, I once wrote a blog post called “Web Serverless,” because the world needs another buzz term, doesn’t it?

Phil Hawksworth: And really, the kind of point of that was, yes, we’re building things without servers. We don’t want to have to manage these servers, and serverless functions, or functions as a service, just fits into that perfectly. So, in the instances that you do need an API that you want to make a request to, where really it’s not sensible for you to make that request directly from the browser. So, for instance, if you’ve got secrets, or keys, in that request, you might not want those requests — that information — ever exposed in the client. But we can certainly proxy those things, and typically, traditionally, what we need to do then, is spin-up a server, have some infrastructure that was effectively doing little more than handling requests, adding security authentication to it and passing those requests on, proxying them back.

Phil Hawksworth: Serverless functions are perfect for that. They’re absolutely ideal for that. So, I sometimes think of serverless functions, or functions of a service, almost as like an escape hatch, where you just need some logic on a server, but you don’t want to have to create an entire infrastructure. And you can do more and more with that, and stipe the development pipelines for, development workflows, for functions as a service is maturing. It’s getting more accessible for JavaScript developers to be able to build these things out. So, yeah, I really think those two things go together very nicely.

Vitaly: All right, that’s a very comprehensive answer. Actually, I attended a talk just recently, where a front-end engineer from Amazon was speaking about serverless and Lamda functions they’re using — I was almost gone. He was always speaking about Docker, and Kubernetes, and all those things, Devox World, I was sitting there, thinking, “How did he end up there. I don’t understand what’s going on!” I had no idea what’s going on.

Phil Hawksworth: Exactly, but the thing is, it used to be the… I was… I accepted that I didn’t understand any of that world, but I didn’t have any desire to, since that was for an entirely different discipline. And that discipline is still really important. You know, people who are designing infrastructure — that’s still really key. But, it just feels, now, that I’m tempted. As someone with a front-end development background, as a JavaScript developer, I’m much more tempted to want to play in that world, because the tools are coming, kind of, closer to me.

Phil Hawksworth: It’s much more likely that I might be able to use some of these things, and deliver things kind of safely, rather than just as an experiment of my own, which is where I used to be dappling. So, it feels like we’re becoming more powerful as web developers, which is exciting to me.

Vitaly: Like Power Rangers, huh?

Vitaly: One thing I do want to ask you, though, and this is actually something we discussed already, maybe, a week ago, but I still wanted to bring it up, because the one thing that you mentioned in the session was the notion of having a stand-alone instance of every single deploy, which is really cool. The question, though, is if you have a large assignment, with tens of thousands of pages, you really don’t want to redeploy every thing, every single time. So, essentially, if you have, like, if you’re mostly using the static side of things. So, we had this idea for a while and I know this is actually something that you brought up last time. The idea of atomic deployments.

Vitaly: Where you actually, literally, were served some sort of div between two different versions of snapshots of the set-up. So, if you say, change the header everywhere, then, of course, every single page has to be redeployed. But if you change, maybe, a component, like let’s say, carousel, that maybe effects only a 1000 pages, then it would make sense to redeploy 15000 pages. But only this 1000. So, can we get there? Is it a magical idea that’s out there, or is it something that’s quite tangible, at this point?

Phil Hawksworth: I think that is, probably, the Holy Grail for static site generators and this kind of model because, certainly, you’ve identified probably the biggest hurdle to overcome. Or the biggest ceiling that you bump into. And that is websites that have many, tens of thousands or hundreds of thousands, or millions of URLs — the notion that the build can become very long. Being able to detect which URL’s will change, based on a code change, is a challenge. It’s not insurmountable, but it’s a big challenge. Understanding what the dependency graph is across your entire site and then, intelligently deploying that — that’s really tough to do.

Phil Hawksworth: Because as you mentioned, a component change might have very far-reaching implications but you — it’s difficult, always, to know how that’s going to work. So, there are a number of static site generators, the projects that are putting some weight behind that challenge, and trying to figure out how they do partial-regeneration and incremental builds. I’m very excited that the prospect that that might get solved day, but at the moment, it’s definitely a big challenge. You can start to do things like try to logically sharred your site, and think about, again, kind of similar to the migration issue. Well, this section I know is independent in terms of its, kind of, some of the assets that it uses, or the type of content that lives there, so I can deploy them individually.

Phil Hawksworth: But that’s not ideal to me. That’s not really the perfect scenario. One of the approaches that I’ve explored a little bit, just as a proof of concept, is thinking about how you do things, like, making intelligent use of 404s. So, for instance, a big use case for very large signs, maybe news sites is, when they need a URL when a breaking news story happens, they need to be first to get it deploy out there. They need to get a URL up there. Things like the BBC News, you’ll see that the news story will arrive on the website, and then overtime, they’ll add to it, incrementally, but getting there first is key. So, having a build that takes 10 minutes, 20 minutes, whatever it’s going to be, that could be a problem.

Phil Hawksworth: But, if they’re content is abstracted and maybe used to have been called from an API. I mentioned content management systems that are abstracted, like Contentful, or Sanity, or a bunch of those. Anything that has a content API changes to that content structure that will trigger a build and we’ll go through the run, but the other thing that could happen is that, well, if you publish your URL for that, and then publicize that URL, even if the build hasn’t run, if someone hicks that URL, if the first stop on its 404 is instead of saying, “We haven’t got it,” is actually to hit that API directly, then, you can say, “Well, the build hasn’t finished to populate that yet, but I can do it in the client.” I can go directly to the API, get that, populate it in the client.

Vitaly: Hmm, interesting.

Phil Hawksworth: So, even while the build is still happening, you can start populating those things. And then, once the build’s finished, of course it wouldn’t hit a 404. You would hit that statically running page. So, there are techniques and there are strategies to tackle it, but still, it’s a very long, rambling answer, I’m sorry, but my conclusion is, yeah, that’s a challenge. Fingers crossed we’ll get better strategies.

Vitaly: Yeah, that’s great. So, I’m wondering, so, at this point, we really aren’t thinking, not just what the performance in terms of the content delivering, but those in performance in terms of the build speed. Like building deployment. So, this is also something that we’ve been looking into for, quite a bit of time now, as well.

Vitaly: One more thing I wanted to ask you. So, this is interesting, like this technique that you mentioned. How do you learn about this? This is just something people tend to publish on their own blogs or, is it some medium or is there a central repository where you can get some sort of case studios, of how JAMstack—how companies moved while unloading, or have failed to move to JAMstack.

Phil Hawksworth: So, it’s kind of maturing this landscape a little bit, at the moment. I mean, some of these examples, I think, I’m in a very fortunate position, I work somewhere that I’m in a role that I’m playing with the toys, coming up with interesting ways to use it and start experimenting with them. So, these proofs of concepts are, kind of, things that I get to experiment with and try to address these challenges. But the, I kind of mentioned earlier, a case study that was shown at the JAMstack conference in New York, and certainly, events like that, we’re starting to see best practices or industry practices and industry approaches being talked about at those kind of events. And certainly, I want to see more and work on more case studies to get in places like on Smashing Magazines, so that we can share this information much more readily.

Phil Hawksworth: I think, large companies and the enterprise space, is gradually adopting JAMstack, in different places, in different ways, but the world is still sloped to get out there, so I think, each time a company adopts it and shares their experience, we all get to learn from that. But I really want to see more and more of these case studies get published, so that we can lean particularly about how these kind of challenges are overcome.

Vitaly: Alright, so, then, maybe just the last question from me, because I always like to read questions. So, the JAMstack land, if you could change something, maybe there is something that you desperately would love to see, beyond deployments. Anything else that would be really making you very happy? That would make your day? What would that be? What’s on your wishlist, for JAMstack?

Phil Hawksworth: What a question. I mean, had we not talked about incremental builds, that would be—

Vitaly: We did. That’s too late, now. This card has been passed, already. We need something else.

Phil Hawksworth: So—

Vitaly: What I mean, like on a platform, if you looked at the back platform, there are so many exciting things happening. We have Houdini, we have web components coming, and everything, since you could be changing the entire landscape of all the right components. On the other side, we have all this magical, fancy world with SS NGS, and, of course, obviously, we also have single-page applications and all. What are you most excited about?

Phil Hawksworth: I’m going to be obtuse here, because there is so much stuff that’s going on, it’s exciting, and there is so many new capabilities that you can make use of in the browser. The thing that I really get excited about is people showing restraint (laughs) and as I said, dull answer, but I love seeing great executions that are done with restraint, in a thoughtful — about the wider audience. It’s really good fun, and gratifying to build with the shiniest new JavaScript library or the new browser API that does, I don’t know, scratch and sniff capabilities in the browser, which we desperately need, any day now.

Phil Hawksworth: But I really like seeing things that I know are going to work in many, many places. They’re going to be really performant, are going to be sympathetic to the browsers that exist — not just on the desks of CEOs and CTOs who got the snazzy toys, but also people who have got much lower-powered devices, or they’ve got challenging network conditions and those kinds of things. I like seeing interesting experiences, and rich experiences, delivered in a way that are sympathetic to the platform, and kind of, compassionate for the wider audience, because I think the web reaches much further than us, the developers, who build things for it. And I get excited by seeing interesting things done, in ways that reach more people.

Phil Hawksworth: That’s probably not the answer you were necessarily—

Vitaly: Oh, that’s a nice ending. Thank you so much. No, that’s perfect, that really is. All right, I felt everything went good! Thank you so much for being with us! I’m handing out to Scott!

Phil Hawksworth: Great!

Vitaly: I’m just here to play questions and answers. So, thank you so much, Phil! I’m still here, but Scott, the stage is yours, now! Maybe you can share with us what’s coming up next on Smashing TV?

Scott: I will, but first, Phil, I can’t wait to see how the implementation of scratch-and-sniff API work. Sounds very interesting. And, Vitaly, JAMstackify is already taken.

Vitaly: (dejected) Taken?! Can we buy it?

Scott: No, it exists!

Vitaly: Well, that’s too late. I’m always late.

Phil Hawksworth: That’s exciting in its own way.

Vitaly: That’s the story of my life. I’m always late.

Scott: Members coming up next, I believe, Thursday, the 13th, we have my ol’ pa, Zach Leatherman, talking about what he talks about best, which is fonts. So, he’s talking about the Five Y’s of Font Implementations. And then, I’m also very interested in the one we have coming up on the 19th, which is editing video, with JavaScript and CSS, with Eva Faria. So, stay tuned for both of those.

Scott: So, that is again, next Thursday, with Zach Leatherman, and then on the 19th, with Eva, who will be talking about editing video in JavaScript and CSS. So, on that note, Phil, I can’t see you anymore, are you still there?

Phil Hawksworth: I’m here!

Scott: On that note, thank you very much everyone! Also, is anybody in the, kind of, close to Toronto area? Or anybody that’s ever wanted to visit Toronto? We have a conference coming up at the end of June, and there’s still a few tickets left. So, maybe we’ll see some of you there.

Vitaly: Thank you so much, everyone else!

Vitaly: Oh, by the way, just one more thing! Maybe Phil mentioned it, but we also have the JAMstack Conference in London, in July. So, that’s something to watch out for, as well. But I’m signing off and going to get my salad! Not sure what you—

Scott: Okay, goodbye, everybody!

Vitaly: All right, bye-bye, everyone.

That’s A Wrap!

We kindly thank Smashing Members from the very bottom of our hearts for their continuous and kind support — and we can’t wait to host more webinars in the future.

Also, Phil will be MCing at SmashingConf Toronto 2019 next week and at JAMstack_conf — we’d love to see you there as well!

Please do let us know if you find this series of interviews useful, and whom you’d love us to interview, or what topics you’d like us to cover and we’ll get right to it.

Smashing Editorial (ra, il)
Privacy Settings
We use cookies to enhance your experience while using our website. If you are using our Services via a browser you can restrict, block or remove cookies through your web browser settings. We also use content and scripts from third parties that may use tracking technologies. You can selectively provide your consent below to allow such third party embeds. For complete information about the cookies we use, data we collect and how we process them, please check our Privacy Policy
Consent to display content from Youtube
Consent to display content from Vimeo
Google Maps
Consent to display content from Google