Applications Of Machine Learning For Designers

artificial intelligence 5291510 1920

Applications Of Machine Learning For Designers

As a designer, you will be facing more demands and opportunities to work with digital systems that embody machine learning. To have your say about how best to use it, you need a good understanding about its applications and related design patterns.

This article illustrates the power of machine learning through the applications of detection, prediction and generation. It gives six reasons why machine learning makes products and services better and introduces four design patterns relevant to such applications. To help you get started, I have included two non-technical questions that will help with assessing whether your task is ready to be learned by a machine.

Further Reading on SmashingMag: Link

Big Data, Small Intelligence Link

Big data and big promises. We are expecting a great many things to happen once the big data deluge has been funnelled into a nurturing stream of bits. Data can be used in many ways. One is to build smart products, and another is to make better design and business decisions. The latter also, ultimately, trickle into products.

Machine learning is a very promising approach radically shaping future product and service development. Machine learning is a branch of artificial intelligence. It employs many methods: Deep learning and neural networks are two well-known instances.

Machine learning means that, instead of programmers providing computers with very detailed instructions on how to perform a task, computers learn the task by themselves. A recent, remarkable milestone was when Google’s AlphaGo software learned to master the game of Go at the level of a world champion!

Pretty much anything that a normal person can do in <1 sec, we can now automate with AI.

– Andrew Ng (@AndrewYNg), 19 October 20165

This story will lead you into problem discovery through examples of what sorts of problems machines today readily chew on. A basic understanding of machine learning, commonly known as ML, will help. If you are unfamiliar with ML, I suggest you read my friendly introduction6 to the topic or Nvidia’s clear explanation7 of the differences between ML, AI and deep learning.

Why Do I Need To Understand The Applications Of Machine Learning? Link

As a designer, you will be facing more demands and opportunities to work with digital systems that embody machine learning. As the hype around machine intelligence intensifies, this will lead to technology-driven pressure to extensively utilize machine learning. This may happen with little understanding of its actual benefits and its impact on product desirability and customer experience.

Stay on Top of the Machine-Intelligence Game! Link

As a designer, to have your say about any plans for machine intelligence and how it is best implemented on the human interface layer, you need to know what it can do and how digital services can utilize it. This post provides an overview of applications, with concrete examples, as well new design guidelines that you can put to work. This will help with making actual design decisions and identifying the right design patterns, including situations when no directly applicable solution exists and you must transfer ideas across domains.

Get To The Core Of The Problem Link

To exploit the capability of machine learning, you must grasp the nature of a task as a computer might see it. The concept I’ll use to describe it is the core problem of learning. This refers to defining what exactly we would like the computer to learn in order for it to complete the task we have assigned to it. These goals are not always evident at the practical, holistic level of a finished product (say, Tesla’s autopilot function). This story will help you to see what goes on under the surface.

Say you want the computer to drive your car.

This is a very high abstraction level learning goal. We need to go further down and break it into smaller chunks. We need to ask questions such as, can the computer accelerate and decelerate, and can the machine recognize red and green lights? To identify the core problem is already a move towards understanding whether the overarching task is a good fit for a machine to learn. Once the core problem of learning is defined well, then it is possible to say whether the ML computers of today can solve it with adequate accuracy and in a decent amount of time. This is what matters most for actually making the application work.

8
Small autonomous buses (in the background) started operating on Aalto University Espoo campus in autumn 2016. The street sign warns about their presence, reminiscent of the first automobiles in the 19th century. (Picture of Project Sohjoa9 demonstration in Espoo. Copyright Metropolia UAS, used with permission.) (View large version10)

What Good Will Machines Do For You? Link

Suppose you manage to teach some skill to a machine. How would your product or service benefit from it? Here are six possible benefits:

  • augment,
  • automate,
  • enable,
  • reduce costs,
  • improve safety,
  • create.

In rare cases, machine learning might enable a computer to perform tasks that humans simply can’t perform because of speed requirements or the scale of data. But most of the time, ML helps to automate repetitive, time-consuming tasks that defy the limits of human labor cost or attentional span. For instance, sorting through recycling waste 24/7 is more reliably and affordably done by a computer.

In some areas, machine learning may offer a new type of expert system that augments and assists humans. This could be the case in design, where a computer might make a proposal for a new layout or color palette aligned with the designer’s efforts. Google Slides already offers this type of functionality through the suggested layouts feature11. Augmenting human drivers would improve traffic safety if a vehicle could, for example, start braking before the human operator could possibly react, saving the car from a rear-end collision.

12
(Large preview13)

Google Slides provides design assistance via the Explore function. Right pane demonstrates the variations it has generated from elements initially composed by the user.

What Have Machines Learned So Far? Link

In 2016, the most celebrated milestone of machine learning was AlphaGo’s victory14 over the world champion of Go, Lee Sedol15. Considering that Go is an extremely complicated game to master, this was a remarkable achievement. Beyond exotic games such as Go, Google Image Search is maybe the best-known application of machine learning. Search feels so natural and mundane when it effectively hides away all of the complexity is embeds. With over 30 billion search queries every day, Google Image Search constantly gets more opportunities to learn.

There are already more individual machine learning applications than are reasonable to list here. But a major simplification16 is not sufficient either, I feel. One way to appreciate the variety is to look at successful ML applications from Eric Siegel’s book Predictive Analytics from 2013. The listed applications fall under the following domains:

  • marketing, advertising and the web;
  • financial risk and insurance;
  • healthcare;
  • crime fighting and fraud detection;
  • fault detection for safety and efficiency;
  • government, politics, nonprofit and education;
  • human-language understanding, thought and psychology;
  • staff and employees, human resources.

His cross-industry collection of examples is a powerful illustration of the omnipresence of predictive applications, even though not all of his 147 examples utilize machine learning as we know it. However, for a designer, knowing whether your problem domain is among the nine listed will give an idea of whether machine learning has already proven to be useful or whether you are facing a great unknown.

Machines Learn Detection, Prediction And Creativity Link

As I see it, the power of learning algorithms comes down to two major applications: detection and prediction. Detection is about interpreting the present, and prediction is about the way of the future. Interestingly, machines can also do generative or “creative” tasks. However these are still a marginal application.

17
Three main categories of ML applications and their common use cases (View large version18)

When you combine detection and prediction, you can achieve impressive overall results. For instance, combine the detection of traffic signs, vehicles and pedestrians with the prediction of vehicular and pedestrian movements and of the times to vehicle line crossings, and you have the makings of an autonomous vehicle!

This is my preferred way of thinking about machine learning applications. In practice, detection and prediction are sometimes much alike because they don’t yet cut into the heart and bones of machine learning (recall the basics of machine learning19), but I believe they offer an appropriate level of abstraction to talk about machine learning applications. Let’s clarify these functions through examples.

The Varieties of Detection Link

There are at least four major types of applications of detection. Each deals with a different core learning problem. They are:

  • text and speech interpretation,
  • image and sound interpretation,
  • human behavior and identity detection,
  • abuse and fraud detection.

Text and Speech Interpretation Link

Text and speech are the most natural interaction and communication methods. Thus, it has not been feasible in the realm of computers. Previous generations of voice dialling and interactive voice response systems were not very impressive. Only in this decade have we seen a new generation of applications that take spoken commands and even have a dialogue with us! This can go so smoothly that we can’t tell computers and humans apart in text-based chats, indicating that computers have passed the Turing test20.

Dealing with speech, new systems such as personal assistant Siri or Amazon’s Echo device are capable of interpreting a wide range of communications and responding intelligently. The technical term for this capability is natural language processing (NLP). This indicates that, based on successful text and speech detection (i.e. recognition), computers can also interpret the meaning of words, spoken and written, and take action.

Text interpretation enables equally powerful applications. The detection of emotion, or sentiment, from text means that large masses of text can be automatically analyzed to reveal what people in social media think about brands, products or presidential candidates. For instance, Google Translate just recently witnessed significant quality improvements21 by switching to an ML approach to translations.

22
Amazon Echo Dot is surfacing as one of the best-selling speech-recognition-driven appliances of early 2017. (View large version23)

Jeff Bezos says the Echo “isn’t about” getting people to shop on Amazon, and he may be right https://t.co/UuDdAms0Yt24pic.twitter.com/erodS8hoJg25

– BI Tech (@SAI) 13 February 201726

Image and Sound Interpretation Link

Computer vision gives metaphorical eyes to a machine. The most radical example of this is a computer reconstruction of human perception from brain scans! However, that is hardly as useful an application as one that automates the tagging of photos or videos to help you explore Google Photos or Facebook. The latter service recognizes faces to an even scary level of accuracy.

Image interpretation finds many powerful business applications in industrial quality control, recording vehicle registration plates, analyzing roadside photos for correct traffic signs, and monitoring empty parking spaces. The recent applications of computer vision to skin cancer diagnosis27 have actually proven more proficient than human doctors, leading to the discovery of new diagnostic criteria!

28
A search for “dog” in my personal Google Photos collection brings up several correct instances of dogs I’ve chanced upon, but also a few false positives. However, I’ve never tagged a single dog, so the noise is acceptable given the added value of finding any dogs. (Screenshot from February 2017, edited to remove personal information (albums).) (View large version29)

Speech was already mentioned, but other audio signals are also well detected by computers. Shazam and SoundHound have for years provided reliable detection of songs either from a recording fragment or a sung melody. The Fraunhofer Institute developed the Silometer30, an app to detect varieties of coughs as a precursor to medical diagnosis. I would be very surprised if we don’t see many new applications for human and non-human sounds in the near future.

Human Behavior and Identity Detection Link

Given that computers are seeing and hearing what we do, it is not surprising that they have became capable of analyzing and detecting human behavior and identity as well — for instance, with Microsoft Kinect recognizing our body motion. Machines can identify movements in a football game to automatically generate game statistics. Apple’s iPad Pro recognizes31 whether the user is using their finger or the pencil for control, to prevent unwanted gestures. A huge number of services detect what kind of items typically go together in a shopping cart; this enables Amazon to suggest that you might also be interested in similar products.

In the world of transportation, it would be a major safety improvement if we could detect when a driver is about to fall asleep behind the steering wheel, to prevent traffic accidents. Identity detection is another valuable function enabled by several signals. A Japanese research institute has developed a car seat32 that recognizes who’s sitting in it. Google’s reCAPTCHA33 is a unique system that tells apart humans from spam bots. Perhaps the most notorious example of guessing people’s health was Target’s successful detection of expectant mothers34. This was followed by a marketing campaign that awkwardly disclosed the pregnancy of Target customers, resulting in much bad publicity.

35
Google’s reCAPTCHA has simplified spam-fighting in web forms with the help of micro-intelligence from machine learning.

Anti-Virus, Anti-Spam, Anti-Malware Link

Machine learning is also used to detect and prevent fraudulent, abusive or dangerous content and schemes. It is not always major attacks; sometimes it is just about blocking bad checks or preventing petty criminals from entering the NFL’s Superbowl arena36. The best successes are found in anti-spam; for instance, Google has been doing an excellent job for years of filtering spam from your Gmail inbox.

I will conclude with a good-willed detection example from the normal human sphere. Whales can be reliably recognized37 from underwater recordings of their sounds — once more, thanks to machine learning. This can help human-made fishing machinery to avoid contact with whales38 for their protection.

39
This humpback whale would be all the merrier if all fishing boats were equipped with machine-learning technology to detect their signals. (View large version40)

Design Pattern: Suggested Features

Text and speech prediction have opened up new opportunities for interaction with smart devices. Conversational interfaces are the most prominent example of this development, but definitely not the only one. As we try to hide the interface and underlying complexity from users, we are balancing between what we hide and what we reveal. Suggested features help users to discover what the invisible UI is capable of.

Graphical user interfaces (GUIs) have made computing accessible for the better part of the human race that enjoys normal vision. GUIs provided a huge usability improvement in terms of feature discovery. Icon and menus were the first useful metaphors for direct manipulation of digital objects using a mouse and keyboard. With multitouch screens, we have gained the new power of pinching, dragging and swiping to interact. Visual clues aren’t going anywhere, but they are not going to be enough when interaction modalities expand.

How Does a User Find Out What Your Service Can Do? Link

Haptic interaction in the first consumer generation of wearables and in the foremost conversational interfaces presents a new challenge for feature discovery. Non-visual cues must be used that facilitate the interaction, particularly at the very onset of the interactive relationship. Feature suggestions — the machine exposing its features and informing the user what it is capable of — are one solution to this riddle.

In the case of a chatbot employed for car rentals, this could be, “Please ask me about available vehicles, upgrades and your past reservations.”

Specific application areas come with specific, detailed patterns. For instance, Patrick Hebron’s recent ebook41 from O’Reilly contains a great discussion of the solutions for conversational interfaces.

Species Of Prediction Link

Several generations of TV watchers have been raised to watch weather forecasts for fun, ever since regular broadcasts began after the Second World War42. The realm of prediction today is wide and varied. Some applications may involve non-machine learning parts that help in performing predictions.

Here I will focus on the prediction of human activities, but note that the prediction of different non-human activities is currently gaining huge interest. Predictive maintenance of machines and devices is one such application, and more are actively envisioned as the Internet of Things generates more data to learn from.

Predicting different forms of human behavior falls roughly into the following core learning challenges and applications:

  • recommendations,
  • individual behavior and condition,
  • collective behavior prediction.

Different types of recommendations are about predicting user preferences. When Netflix recommends a movie or Spotify generates a playlist of your future favorite music, they are trying to predict whether you will like it, watch it or listen through to the end of the piece. Netflix is on the lookout for your rating of the movie afterwards, whereas Spotify or Pandora might measure whether you are returning to enjoy the same song over and over again without skipping. This way, our behaviors and preferences become connected even without our needing to express them explicitly. This is something machines can learn about and exploit.

In design, predicting which content or which interaction models appeal to users could give rise to the personalization of interfaces. This is mostly based on predicting which content a user would be most interested in. For a few years now, Amazon has been heavily personalizing the front page, predicting what stuff and links should be present in anticipation of your shopping desires and habits.

Recommendations are a special case of predicting individual behavior. The scope of predictions does not end with trivial matters, such as whether you like Game of Thrones or Lady Gaga. Financial institutions attempt to predict who will default on their loan or try to refinance it. Big human-resource departments might predict employee performance and attrition. Hospitals might predict the discharge of a patient or the prognosis of a cancer. Rather more serious humans conditions, such as divorce, premature birth and even death within a certain timeframe, have been all been predicted with some success. Of course, predicting fun things can get serious when money is involved, as when big entertainment companies try to guess which songs43 and movies will top the charts to direct their marketing and production efforts.

44
Microsoft’s ML platform demonstrator How Old Do I Look?45 guesses age (a human condition) based on any uploaded photo or search.

The important part about predictions is that they lead to individual assessment that are actionable. The more reliable the prediction and the weightier the consequences, the more profitable and useful the predictions become.

Predicting collective behavior becomes a generalization of individuals but with different implications and scope. In these cases, intervention is only successful if it affects most of the crowd. The looming result of a presidential election, cellular network use or seasonal shopping expenditure can all be subject to prediction. When predicting financial risk or a company’s key performance indicators, the gains of saving or making money are noticeable. J.P. Morgan Chase was one of the first banks to increase efficiency by predicting mortgage defaulters (those who never pay back) and refinancers (those who pay back too early). On the other hand, the recent US presidential election is a good reminder that none of this is yet perfect.

In a close resemblance to tools for antivirus and other present dangers, future trouble is also predictable. Predictive policing is about forecasting where street conflicts might happen or where squatters are taking over premises, which would help administrators to distribute resources to the right places. A similar process is going on in energy companies, as they try to estimate the capacity needed to last the night.

Design Pattern: Personalization

Once a computer gets to know you and to predict your desires and preferences, it can start to serve you in new, more effective ways. This is personalization, the automated optimization of a service. Responsive website layouts are a crude way of doing this.

The utilization of machine learning features with interfaces could lead to highly personalized user experiences. Akin to giving everyone a unique desktop and homescreen, services and apps will start to adapt to people’s preferences as well. This new degree of personalization presents opportunities as well as forces designers to flex their thoughts on how to create truly adaptive interfaces that are largely controlled by the logic of machine learning. If you succeed in this, you will reward users with a superior experience and will impart a feeling of being understood46.

47
Amazon.com’s front page has been personalized for a long time. The selection offered to me looks somewhat relevant, if not attractive. (View large version48)

Currently, personalization is foremost applied in order to curate content. For instance, Amazon carefully considers which products would appeal to potential buyers on its front page. But it will not end with that. Personalization will likely lead to much bigger changes across UIs — for instance, even in the presentation of the types of interactive elements a user likes to use.

Questions To Ask In Considering The Fit Of Machine Learning Link

Say you are now convinced that your users and customers would benefit from a ML-boosted service. Next, you must consider the business and technology perspectives. The first question to ask is, If ML works at least as well as you want, what value would it add to your product? Be honest: Traditional business logic applies here, too.

If machine learning doesn’t create value, then it is probably a waste of resources. Marketing people might fancy your new implementation, but the business folks will not necessarily fund your next machine learning experiment unless you have a business case for why machine learning would improve the customer experience or revenue directly.

OK, suppose you’ve cleared the viability check box. I expect you also have at least a hypothesis of the core learning challenge. This might be, for example, Can a computer learn to predict when the user would need to take an umbrella or a waterproof jacket when they leave the house in the morning.

Next, you’ll need to figure out whether you can expect the machine to learn the job you wish to get done. We’ve come to matters of data. Data broadly refers to any information you can feed the computer: weather data, shopping data for umbrellas and waterproof gear, social media updates and so forth.

Here are two simple diagnostic questions to assess the data situation:

  • Do we have enough examples for the machine to learn from?
  • Are there patterns in the teaching material that can be recognized by a human expert?

The first question looks easy but is difficult to answer in advance. You need both good quality and a sufficient quantity of data. Some signals are noisy (that is, have poor quality). You might need more examples in these cases than in others. Some features are very prominent and easy to learn, such as in the case of detecting nighttime or daytime in photos. This can be solved with as few as 30 training images49!

Typical applications require thousands of instances of input data and possibly the desired answers. The more complicated the task, the more material will be needed. AlphaGo learned to master the game after analyzing a staggering 30 million games50 and then playing some against itself! This is likely excessive in most situations, but it gives you an idea of the scale of what computers can and may need to swallow — from 30 to 30 million. This is one of the reasons why increasing computing capacity and certain hardware really makes computers smarter by speeding up the learning of truly big data.

51
The complexity of Go pushed machine learning capacity to its extremes. Playing the game at random, or by brute force, would be futile. (Image: YouTube52) (View large version53)

The second question is, Are there patterns in the teaching material that can be recognized by a human expert? If a human can do the task, then there’s a fair chance that there are regularities in the data that might be picked up by the computer as well.

If you have a positive answer to least one of the questions, you can go forward with some confidence that machine learning might indeed be of use to you. What you’d do after this discovery is mostly beyond the scope of this article.

In order to build a machine learning solution, it is best to boldly go and prototype your desired functionality. If you have enough samples, your data scientist teammate will quickly discover whether the machine shows proficiency in the learning task (particularly if you use scalable could computing). If not, you’ll need to get more data.

What follows is a series of iterations on the learning mechanisms and a process of integrating it with the product or service. The appearance of intelligent applications can be achieved by carefully putting together several pieces of machine learning and even conventional programming. This is called an ensemble approach. What at best appears as a seamless interactive experience for the user may in fact be the product of a very complex rubric of different machine learning components working together.

Human intelligence is heavily needed to tweak the learning algorithms. Such was the architecture underlying Watson54, the Jeopardy-winning artificial intelligence system created by IBM and the algorithm that claimed the Netflix Prize55. In the latter competition, several teams combined their individual tweaks during the final months of the competition to eventually exceed the criteria for success. This is also what the Google Translate team did to ascend to the next level. And that work is something I consider to fall under the domain of traditional software development.

New Design Patterns For Creating Interfaces Of Machine Learning Applications! Link

56
Illustration: Joonas Haverinen, SC5 (Large preview57)

Thus far, I’ve talked about the possibilities of machine learning and given some practical advice on how to figure out its feasibility. I’ve also introduced two general design patterns that are tightly connected to machine learning. However, they are not enough.

A designer engaged in service and interface design will have several questions concerning interaction in their mind by now. How can we and will we communicate machine intelligence to users, and what kinds of new interfaces will machine learning call for?

This entails both opportunities to do things in a new way, as well as requirements for new designs. To me, this means we will need a rise in importance of several design patterns or, rather, abstract design features, which will become important as services get smarter. They include:

  • suggested features,
  • personalization,
  • shortcuts versus granular controls,
  • graceful failure.

I have already covered suggested features58 and personalization59 as a part of detection and prediction, but what are granularity and graceful failure?

Design Pattern: Shortcuts Versus Granularity Link

Photoshop is an excellent example of a tool with a steep learning curve and a great deal of granularity in controlling what can be done. Most of the time, you work on small operations, each of which has a very specific influence. The creative combination of many small things allows for interesting patterns to emerge on a larger scale. Holistic, black-box operations such as transformative filters and automatic corrections are not really the reason why professionals use Photoshop.

What will happen when machines learn to predict what we are doing repeatedly? For instance, I frequently perform certain actions in Photoshop before uploading my photos to a blog. While I could manually automate this, creating yet another user-defined feature among thousands already in the product, Photoshop might learn to predict my intentions and offer a more prominent shortcut, or a highway, to fast-forward me to my intended destination. As Adobe currently puts effort into bringing AI into Creative Cloud, we’ll likely see something even more clever than this very soon. It is up to you to let the machine figure out the appropriate shortcuts in your application.

60
A mockup of a possible implementation of “predictive history” in Photoshop CC. The application suggests a possible future state for the user based on the user’s history and preceding actions and on the current image. (View large version61)

A funny illustration of a similar train of thought comes from Cristopher Hesse’s machine-learning-based image-to-image translation62, which provides interesting content-specific filling of doodles. Similar to Photoshop’s content-aware fill, it creates most hilarious visualizations of building facades, cats, shoes and bags based on minimal user input.

63
The edges2cats algorithm employs machine learning to finish your cat doodle as a photorealistic cat monster. (View large version64)

Design Pattern: Graceful Failure Link

I call the final pattern graceful failure. It means saying “sorry, I can’t do what you want because…” in an understandable way.

This is by no means unique to machine learning applications. It is innately human, but something that computers have been notoriously bad at since the time that syntax errors were repeatedly echoed by Commodore computers in the 1980s. But with machine learning, it’s slightly different. Because machine learning takes a fuzzy-logic approach to computing, there are new ways that the computer could produce unexpected results — that is, things could go very bad, and that has to be designed for. Nobody seriously blames the car in question for the death that occurred in the Tesla autopilot accident in 2016.

The other part is that building applications that rely on modern machine learning is still in its infancy. Classic software development has been around for so long that we’ve learned to deal with its insufficiencies better. As Peter Norvig, famous AI researcher and Google’s research director, puts it like this65:

The problem here is the methodology for scaling this up to a whole industry is still in progress.… We don’t have the decades of experience that we have in developing and verifying regular software.

The nature of learning is such that computers learn from what is given to them. If the algorithm has to deal with something else, then the results will not be to your liking. For example, if you’ve trained a system to detect animal species from pet photos and then start using it to classify plants, there will be trouble. This is more or less why Microsoft’s Twitterbot Tay had to be silenced66 after it picked up the wrong examples from malicious users when exposed to real-world conditions.

The uncertainty in detection and prediction should be taken into consideration. How this is done depends on the application. Consider Google Search. No one is offended or truly hurt, but merely amused or frustrated, by bad search results. Of course, bad results will eventually be bad for business. However, if your bank started using a chatbot that suddenly could not figure out your checking account’s balance, you would be rightfully worried and should be offered a quick way to resolve your trouble.

To deal with failure, interfaces would do well to help both parties adjust. Users can tolerate one or two “I didn’t get that, please say that again” prompts (but no more) if that’s what it takes to advance the dialogue. For services that include machine learning, extensive testing is best. Next comes informing users about the probability and consequences of failure, and instructions on what the user might do to avoid it. The good practices are still emerging.

Summary Link

With machine learning, our vision of tomorrow is quickly becoming today’s reality.

Overall, there hardly seems to be an application that machine learning could not be used to detect or predict. I’ve introduced plenty of examples of deploying machine learning to varying success. In all of the examples, I’ve tried to illustrate some core learning challenge to help you understand what sorts of tasks machines respond to. Now it is time to face the question of what machine learning can do for you!

I don’t expect that this guide alone will suffice for radical innovation in the sphere of intelligent products and services. I do hope that it will open the eyes of several designers to the opportunities that machine learning solutions afford us today. It is important to understand approximately what you can realistically ask from a machine. In the near future, good questions will become ever more important, so that the answer will be, “Yes, Dave. I can do that.”

Thanks to Max Pagels, Janne Aukia, Antti Rauhala, Teemu Kinnunen and Patrick Hebron for discussing the topic.

Further Resources Link

Article by Fabien Girardin: Experience Design in the Machine Learning Era67

Article by Neal Lathia: Machine learning for product managers68

Video of Andrew Ng: Artificial Intelligence is the New Electricity69 (Stanford GSB). Ng talks of product management, but his insights are relevant to design as well.

(rb, yk, al, il)

Footnotes Link

  1. 1 https://www.smashingmagazine.com/2017/01/algorithm-driven-design-how-artificial-intelligence-changing-design/
  2. 2 https://www.smashingmagazine.com/2016/12/conversational-design-essentials-tips-for-building-a-chatbot/
  3. 3 https://www.smashingmagazine.com/2016/11/does-conversation-hurt-or-help-the-chatbot-ux/
  4. 4 https://www.smashingmagazine.com/2016/07/conversational-interfaces-where-are-we-today-where-are-we-heading/
  5. 5 https://twitter.com/AndrewYNg/status/788548053745569792
  6. 6 https://sc5.io/posts/basics-of-machine-learning/
  7. 7 https://blogs.nvidia.com/blog/2016/07/29/whats-difference-artificial-intelligence-machine-learning-deep-learning-ai/
  8. 8 https://www.smashingmagazine.com/wp-content/uploads/2017/03/AMLD-Robot_bus_warning-large-opt.jpg
  9. 9 http://sohjoa.fi/
  10. 10 https://www.smashingmagazine.com/wp-content/uploads/2017/03/AMLD-Robot_bus_warning-large-opt.jpg
  11. 11 https://support.google.com/docs/answer/7130307?co=GENIE.Platform%3DDesktop&hl=en
  12. 12 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Google_Presentation_Explore-large-opt.jpg
  13. 13 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Google_Presentation_Explore-large-opt.jpg
  14. 14 https://gogameguru.com/tag/deepmind-alphago-lee-sedol/
  15. 15 https://gogameguru.com/tag/deepmind-alphago-lee-sedol/
  16. 16 https://hbr.org/2016/11/what-artificial-intelligence-can-and-cant-do-right-now
  17. 17 https://www.smashingmagazine.com/wp-content/uploads/2017/03/AMLD-Table_of_functions-large-opt.png
  18. 18 https://www.smashingmagazine.com/wp-content/uploads/2017/03/AMLD-Table_of_functions-large-opt.png
  19. 19 https://sc5.io/posts/basics-of-machine-learning/
  20. 20 http://www.bbc.com/news/technology-27762088
  21. 21 https://www.nytimes.com/2016/12/14/magazine/the-great-ai-awakening.html
  22. 22 https://www.smashingmagazine.com/wp-content/uploads/2017/03/AMLD-Amazon-Echo-Dot-large-opt.jpg
  23. 23 https://www.smashingmagazine.com/wp-content/uploads/2017/03/AMLD-Amazon-Echo-Dot-large-opt.jpg
  24. 24 https://t.co/UuDdAms0Yt
  25. 25 https://t.co/erodS8hoJg
  26. 26 https://twitter.com/SAI/status/831244067191345152
  27. 27 http://www.computerworld.com/article/2860758/ibm-detects-skin-cancer-more-quickly-with-visual-machine-learning.html
  28. 28 https://www.smashingmagazine.com/wp-content/uploads/2017/03/AMLD-Google_Photos_tagging-large-opt.jpg
  29. 29 https://www.smashingmagazine.com/wp-content/uploads/2017/03/AMLD-Google_Photos_tagging-large-opt.jpg
  30. 30 https://play.google.com/store/apps/details?id=de.fraunhofer.idmt.hsa.Silometer&hl=en
  31. 31 https://backchannel.com/an-exclusive-look-at-how-ai-and-machine-learning-work-at-apple-8dbfb131932b
  32. 32 http://newatlas.com/japanese-car-seat-identification/20947/
  33. 33 https://security.googleblog.com/2014/12/are-you-robot-introducing-no-captcha.html
  34. 34 http://www.nytimes.com/2012/02/19/magazine/shopping-habits.html
  35. 35 https://www.smashingmagazine.com/wp-content/uploads/2017/03/AMLD-ReCaptcha-large-opt.png
  36. 36 https://www.wired.com/2001/02/call-it-super-bowl-face-scan-i/
  37. 37 http://danielnouri.org/notes/2014/01/10/using-deep-learning-to-listen-for-whales/
  38. 38 http://www.meetcortex.com/blog/how-machine-learning-can-save-the-whale/
  39. 39 https://www.smashingmagazine.com/wp-content/uploads/2017/03/AMLD-Humpback_whale_pixabay-large-opt.jpg
  40. 40 https://www.smashingmagazine.com/wp-content/uploads/2017/03/AMLD-Humpback_whale_pixabay-large-opt.jpg
  41. 41 http://www.oreilly.com/design/free/machine-learning-for-designers.csp
  42. 42 https://en.wikipedia.org/wiki/Weather_forecasting#Broadcasts
  43. 43 http://www.wired.co.uk/article/song-prediction-algorithm
  44. 44 https://how-old.net/
  45. 45 https://how-old.net/
  46. 46 http://www.slideshare.net/UXSTRAT/ux-strat-usa-belmer-negrillo-a-personalization-model-for-adaptive-learning
  47. 47 https://www.smashingmagazine.com/wp-content/uploads/2017/03/AMLD-Amazon_personalization-large-opt.png
  48. 48 https://www.smashingmagazine.com/wp-content/uploads/2017/03/AMLD-Amazon_personalization-large-opt.png
  49. 49 https://www.wolfram.com/mathematica/new-in-10/highly-automated-machine-learning/distinguish-daytime-from-nighttime-pictures.html
  50. 50 https://www.tastehit.com/blog/google-deepmind-alphago-how-it-works/
  51. 51 https://www.smashingmagazine.com/wp-content/uploads/2017/03/AMLD-AlphaGo-game-large-opt.png
  52. 52 https://www.youtube.com/watch?v=vFr3K2DORc8
  53. 53 https://www.smashingmagazine.com/wp-content/uploads/2017/03/AMLD-AlphaGo-game-large-opt.png
  54. 54 https://www.quora.com/Whats-the-system-architecture-of-the-IBM-Watson
  55. 55 https://en.wikipedia.org/wiki/Netflix_Prize
  56. 56 https://www.smashingmagazine.com/wp-content/uploads/2017/03/AMLD-Four_design_patterns-large-opt.png
  57. 57 https://www.smashingmagazine.com/wp-content/uploads/2017/03/AMLD-Four_design_patterns-large-opt.png
  58. 58 #suggested
  59. 59 #personalization
  60. 60 https://www.smashingmagazine.com/wp-content/uploads/2017/03/AMLD-Photoshop-ML-prediction-large-opt.jpg
  61. 61 https://www.smashingmagazine.com/wp-content/uploads/2017/03/AMLD-Photoshop-ML-prediction-large-opt.jpg
  62. 62 http://affinelayer.com/pixsrv/index.html
  63. 63 https://www.smashingmagazine.com/wp-content/uploads/2017/03/AMLD-Edges2cats-large-opt.png
  64. 64 https://www.smashingmagazine.com/wp-content/uploads/2017/03/AMLD-Edges2cats-large-opt.png
  65. 65 http://events.technologyreview.com/video/watch/peter-norvig-state-of-the-art-ai/
  66. 66 https://techcrunch.com/2016/03/24/microsoft-silences-its-new-a-i-bot-tay-after-twitter-users-teach-it-racism/
  67. 67 https://medium.com/@girardin/experience-design-in-the-machine-learning-era-e16c87f4f2e2
  68. 68 https://hackernoon.com/machine-learning-for-product-managers-ba9cf8724e57#.leqry3khu
  69. 69 https://www.youtube.com/watch?v=21EiKfQYZXc&feature=youtu.be&t=43m16s

↑ Back to topTweet itShare on Facebook

Web Development Reading List #179: Firefox 53, The Top Web Browsers, And Vue.js Authentication

artificial intelligence 5291510 1920

Web Development Reading List #179: Firefox 53, The Top Web Browsers, And Vue.js Authentication

Bots and Artificial Intelligence are probably the most hyped concepts right now. And while some people praise the existing technologies, others claim they don’t fear AI at all, citing examples where it fails horribly. Examples of Facebook or Amazon advertising (both claim to use machine learning) that don’t match our interests at all are quite common today.

But what happens if we look at autonomous cars, trains or planes that have the very same machine learning technologies in place? How about the military using AI for its actions? While we’re still experimenting with these capable technologies, we also need to consider the possible consequences, the responsibilities that we have as developers and how all of this might affect the people the technology is being served to.

Further Reading on SmashingMag: Link

News Link

  • This week, Firefox 53 rolled out5 to end users, shipping performance benefits, positioned CSS Masks, and the new display: flow-root value that effectively replaces our common clearfix methods6. The update also comes with a revamped media player design. Finally, this is the first Firefox version without Windows XP and Vista support, so if you rely on one of these operating systems, consider switching to the ESR version of Firefox and upgrade to a newer system as soon as possible (the OS are not supported by Microsoft anymore).
  • Chrome 587 comes with support for IndexedDB 2.0, fullscreen support for progressive web apps, and improvements for sandboxed iframes. Alongside Firefox 53, the new Chrome is the second browser to support display: flow-root, the new clearfix replacement8. There’s also PointerEvents.getCoalescedEvents() as a new method to give you access to all input events that took place since the last time a PointerEvent was delivered — a useful feature for drawing applications but also quite risky when we look at it from a privacy and user tracking perspective.
  • Mozilla finally simplified the developer experience and got rid of the Firefox Developer Edition9. If you still use it, switch to the Firefox Nightly Edition10. While there’s still a beta channel, I recommend Nightly as it’s relatively free of bugs that impact the general usage while supporting the latest features, deprecations and development tools already weeks or even months ahead of public launch. This is great as you have more time to adjust code on live sites when something breaks in the Nightly channel. I use WebKit Nightly and Chrome Canary similarly.

General Link

  • Peter O’Shaughnessy challenges us to estimate which web browsers have the most users11. And as you can probably assume, our existing idea of Chrome, Firefox, Safari, and IE leading the field isn’t up to date anymore. Instead, we need to acknowledge that UC Browser has an impressive market share, Opera Mini still does, too, Yandex in certain regions and Samsung Internet usage grows fast as more devices are shipped with it. And Google Analytics isn’t telling us the truth anyway — big parts of “Chrome” might actually be Samsung Internet.
12
Browser usage13 on mobile as of February 2017. Not as you would have expected, right? (Image credit14)

Concept & Design Link

Tools & Workflows Link

  • Google Chrome can now be run in headless mode, replacing PhantomJS or SlimerJS. Jim Cummins explains how to set it up on Mac OS16. For Windows and Linux it should be similar using bash and a few adaptions to the local commands.

Security Link

Privacy Link

  • Jeremy Thomas experimented with browsers and tried to disable cookies entirely19. Read about how successful he was with it and what challenges he faced with modern web applications.
Browsing Soundcloud with cookies disabled isn’t possible20
What happens when you disable cookies completely21? Well, some sites don’t even load, on others, basic interactions aren’t possible anymore. (Image credit22)

Accessibility Link

JavaScript Link

And with that, I’ll close for this week. If you like what I write each week, please support me with a donation26 or share this resource with other people. You can learn more about the costs of the project here27. It’s available via email, RSS and online.

— Anselm

Footnotes Link

  1. 1 https://www.smashingmagazine.com/2016/06/the-current-state-of-authentication-we-have-a-password-problem/
  2. 2 https://www.smashingmagazine.com/2016/12/conversational-design-essentials-tips-for-building-a-chatbot/
  3. 3 https://www.smashingmagazine.com/2016/09/how-to-design-error-states-for-mobile-apps/
  4. 4 https://www.smashingmagazine.com/2016/02/writing-next-generation-reusable-javascript-modules/
  5. 5 https://hacks.mozilla.org/2017/04/firefox-53-quantum-compositor-compact-themes-css-masks-and-more/
  6. 6 https://helloanselm.com/2017/flow-root-supports/
  7. 7 https://developers.google.com/web/updates/2017/04/nic58
  8. 8 https://helloanselm.com/2017/flow-root-supports/
  9. 9 https://hacks.mozilla.org/2017/04/simplifying-firefox-release-channels/
  10. 10 https://nightly.mozilla.org/
  11. 11 https://medium.com/samsung-internet-dev/think-you-know-the-top-web-browsers-458a0a070175
  12. 12 https://medium.com/samsung-internet-dev/think-you-know-the-top-web-browsers-458a0a070175
  13. 13 https://medium.com/samsung-internet-dev/think-you-know-the-top-web-browsers-458a0a070175
  14. 14 https://medium.com/samsung-internet-dev/think-you-know-the-top-web-browsers-458a0a070175
  15. 15 https://simpleicons.org/
  16. 16 https://objectpartners.com/2017/04/13/how-to-install-and-use-headless-chrome-on-osx/
  17. 17 http://www.martinvigo.com/design-flaws-lastpass-2fa-implementation/
  18. 18 https://auth0.com/blog/vuejs2-authentication-tutorial/
  19. 19 http://jgthms.com/browsing-the-web-with-cookies-disabled.html
  20. 20 http://jgthms.com/browsing-the-web-with-cookies-disabled.html
  21. 21 http://jgthms.com/browsing-the-web-with-cookies-disabled.html
  22. 22 http://jgthms.com/browsing-the-web-with-cookies-disabled.html
  23. 23 https://hiddedevries.nl/en/blog/2017-04-04-how-to-make-error-messages-accessible
  24. 24 http://meulta.com/en/2017/04/17/bot-framework-web-chat-and-push-notifications/
  25. 25 https://www.contentful.com/blog/2017/04/04/es6-modules-support-lands-in-browsers-is-it-time-to-rethink-bundling/
  26. 26 https://wdrl.info/donate
  27. 27 https://wdrl.info/costs/

↑ Back to topTweet itShare on Facebook

Jekyll For WordPress Developers

artificial intelligence 5291510 1920

Jekyll For WordPress Developers

Jekyll is gaining popularity as a lightweight alternative to WordPress. It often gets pigeonholed as a tool developers use to build their personal blog. That’s just the tip of the iceberg — it’s capable of so much more!

In this article, we’ll take on the role of a web developer building a website for a fictional law firm1. WordPress is an obvious choice for a website like this, but is it the only tool we should consider? Let’s look at a completely different way of building a website, using Jekyll.

Further Reading on SmashingMag: Link

What Is Jekyll? Link

Jekyll6 is a static website generator. Instead of software and a database being installed on our server, a Jekyll website is simply a directory of files on our computer. When we run Jekyll on that directory, it generates a static website, which we upload to a hosting provider.

Why Jekyll? Link

We need to consider a number of tradeoffs when deciding whether Jekyll is right for a project.

Advantages of Jekyll Link

  • Less complexity

    A Jekyll website is essentially a static website with a templating language. It has fewer components to create and maintain. On the server, we only need a web server capable of serving files.
  • Speed

    When visitors view pages on Jekyll sites, the server returns existing files without any extra processing. This is much faster than WordPress, which generates pages dynamically at request time. Note: WordPress Caching plugins can eliminate this performance gap.
  • Stability

    WordPress has more components working together to generate pages for visitors. If a component fails, visitors may not be able to view the website. Much less can go wrong when a web server is serving only files.
  • Security

    WordPress does a lot to mitigate security risks such as CSRF, XSS, or SQL injection attacks however it relies on you always having the latest updates. Statics sites eliminate this problem because there’s no dynamic data storage a hacker can exploit.
  • Source-controlled

    A Jekyll website is a directory of files, so we can store the entire website in a Git repository. Working with a repository gives us many benefits7 (although VersionPress8 is in development and enables this workflow for WordPress).

Disadvantages of Jekyll Link

  • No GUI

    A client can sign up to WordPress.com, choose a theme and set up a basic website by themselves. Jekyll is a command-line tool, which overwhelms most non-technical users. There are third-party GUIs for Jekyll, including CloudCannon9 (disclaimer: I’m the cofounder), Forestry10, Jekyll Admin11, Netlify CMS12, Prose13 and Siteleaf14. However, these need to be set up by the developer before being handed off to the client.
  • Build time

    In our situation, this isn’t a problem because the website will build in under a second. However, a larger website with 10,000 to 100,000 posts could take minutes to build. This is frustrating when we’re developing because we have to wait for the website to build before previewing it in the browser.
  • Themes

    Jekyll has some themes available, but it’s nothing compared to the thousands of themes available for WordPress.
  • Extensibility

    If we need to add custom functionality to our WordPress website, we can write our own PHP. We can create custom Ruby plugins for Jekyll, however, these run at build time rather than request time.
  • Support

    WordPress has a huge community of experts and other resources to help. Jekyll has similar resources but on a smaller scale.

Jekyll is a great tool for largely informational websites, like this project. If the project is more of an application, we could add dynamic elements using JavaScript, but at some point we would probably need a back end like WordPress’.

Implementation Link

WordPress and Jekyll take different approaches to building a website yet share a lot of functionality. Let’s get started building our Jekyll website.

Installing Link

A typical development environment for WordPress requires installation of Apache or NGINX, PHP and MySQL. Then, we would install WordPress and configure the web server.

For Jekyll, we need to make sure we have Ruby installed (sometimes this is harder than it sounds). Then we install the Jekyll gem:

gem install jekyll

If you’re on macOS make sure you have Xcode developer installed first.

xcode-select --install

Running Link

Running a WordPress site usually consists of starting the database and web server.

In Jekyll, we navigate to our site files (an empty directory at this point) in the terminal and run:

jekyll serve

This starts a local web server on port 4000 and rebuilds the site whenever a file changes.

Pages Link

It’s time to create our first page. Let’s start with the home page. Pages are for standalone content without an associated date. WordPress stores page content in the database.

In Jekyll, pages are HTML files. We’ll start with pure HTML and then add Jekyll features as they’re needed. Here’s index.html in its current state:

<html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="http://www.smashingmagazine.com/css/main.css"> </head> <body> <div> <h1><a href="http://www.smashingmagazine.com/">Justice</a></h1> <nav> <ul> <li><a href="http://www.smashingmagazine.com/about/">About</a></li> <li><a href="http://www.smashingmagazine.com/services/">Services</a></li> <li><a href="http://www.smashingmagazine.com/contact/">Contact</a></li> <li><a href="http://www.smashingmagazine.com/advice/">Advice</a></li> </ul> </nav> </div> <section> <div> <p>Justice Law is professional representation. Practicing for over 50 years, our team have the knowledge and skills to get you results.</p> <blockquote> <p>Justice Law are the best of the best. Being local, they care about people and have strong ties to the community.</p> <p> <img src="/images/peter.jpeg" alt="Photo of Peter Rottenburg"> Peter Rottenburg </p> </blockquote> </div> </section> <footer> <p> &copy; 2016 </p> </footer> </body> </html> 

Liquid Link

In WordPress, we can write PHP to do almost anything. Jekyll takes a different approach. Instead of providing a full programming language, it uses a templating language named Liquid15. (WordPress has templating languages, too, such as Timber16.)

The footer of index.html contains a copyright notice with a year:

<p> &copy; 2016 </p> 

We’re unlikely to remember to update this every year, so let’s use Liquid to output the current year:

<p> &copy; {{ site.time | date: "%Y" }} </p> 

We’re building a static website in Jekyll, so this date won’t change until we rebuild the website. If we wanted the date to change without having to rebuild the website, we could use JavaScript.

Includes Link

The bulk of the HTML in index.html is for setting up the overall layout and won’t change between pages. This repetition will lead to a lot of maintenance, so let’s reduce it.

Includes were one of the first things I learned in PHP. Using includes, we can put the header and footer content in different files, then include the same content on multiple pages.

Jekyll has exactly the same feature. Includes are stored in a folder named _includes. We use Liquid to include them in index.html:

{% include header.html %} <p>Justice Law is professional representation. Practicing for over 50 years, our team have the knowledge and skills to get you results.</p> <blockquote> <p>Justice Law are the best of the best. Being local, they care about people and have strong ties to the community.</p> <p> <img src="/images/peter.jpeg" alt="Photo of Peter Rottenburg"> Peter Rottenburg </p> </blockquote> {% include footer.html %} 

Layouts Link

Includes reduce some of the repetition, but we still have them on each page. WordPress solves this problem with template files that separate a website’s structure from its content.

The Jekyll equivalent to template files is layouts. Layouts are HTML files with a placeholder for content. They are stored in the _layouts directory. We’ll create _layouts/default.html to contain a basic HTML layout:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="http://www.smashingmagazine.com/css/main.css"> </head> <body> <div> <h1><a href="http://www.smashingmagazine.com/">Justice</a></h1> <nav> <ul> <li><a href="http://www.smashingmagazine.com/about/">About</a></li> <li><a href="http://www.smashingmagazine.com/services/">Services</a></li> <li><a href="http://www.smashingmagazine.com/contact/">Contact</a></li> <li><a href="http://www.smashingmagazine.com/advice/">Advice</a></li> </ul> </nav> </div> <section> <div> {{ content }} </div> </section> <footer> <p> &copy; {{ site.time | date: "%Y-%m-%d" }} </p> </footer> </body> </html> 

Then, replace the includes in index.html by specifying the layout. We specify the layout using front matter, which is a snippet of YAML17 that sits between two triple-dashed lines at the top of a file (more on this soon).

--- layout: default --- <p>Justice Law is professional representation. Practicing for over 50 years, our team have the knowledge and skills to get you results.</p> <blockquote> <p>Justice Law are the best of the best. Being local, they care about people and have strong ties to the community.</p> <p> <img src="/images/peter.jpeg" alt="Photo of Peter Rottenburg"> Peter Rottenburg </p> </blockquote> 

Now we can have the same layout on all of our pages.

Front Matter Link

In WordPress, custom fields allow us to set meta data on a post. We can use them to set SEO tags or to show and hide sections of a page for a particular post.

This concept is called front matter18 in Jekyll. Earlier, we used front matter to set the layout for index.html. We can now set our own variables and access them using Liquid. This further reduces repetition on our website.

Let’s add multiple testimonials to index.html. We could copy and paste the HTML, but once again, that leads to increased maintenance. Instead, let’s add the testimonials in front matter and iterate over them with Liquid:

--- layout: default testimonials: - message: We use Justice Law in all our endeavours. They offer an unparalleled service when it comes to running a business. image: "/images/joice.jpeg" name: Joice Carmold - message: Justice Law are the best of the best. Being local, they care about people and have strong ties to the community. image: "/images/peter.jpeg" name: Peter Rottenburg - message: Justice Law were everything we could have hoped for when buying our first home. Highly recommended to all. image: "/images/gibblesto.jpeg" name: D. and G. Gibbleston --- <p>Justice Law is professional representation. Practicing for over 50 years, our team have the knowledge and skills to get you results.</p> <div> {% for testimonial in page.testimonials %} <blockquote> <p>{{ testimonial.message }}</p> <p> <img src="{{ testimonial.image }}" alt="Photo of {{ testimonial.name }}"> {{ testimonial.name }} </p> </blockquote> {% endfor %} </div> 

Posts Link

WordPress stores the HTML content, date and other meta data for posts in the database.

In Jekyll, each post is a static file stored in a _posts directory. The file name has the publication date and title for the post — for example, _posts/2016-11-11-real-estate-flipping.md. The source code for a blog post takes this structure:

--- layout: post categories: - Property --- Flipping is a term used primarily in the US to describe purchasing a revenue-generating asset and quickly reselling it for profit. ![House](/images/house.jpeg) 

We can also use front matter to set categories and tags.

Below the front matter is the body of the post, written in Markdown19. Markdown is a simpler alternative to HTML.

Jekyll allows us to create layouts that inherit from other layouts. You might have noticed this post has a layout of post. The post layout inherits from the default layout and adds a date and title:

--- layout: default --- <h3>{{ page.title }}</h3> <p>{{ page.date | date: '%B %d, %Y' }}</p> {{ content }} 

Let’s create blog.html to iterate over the posts and link to them:

--- layout: default --- <ul> {% for post in site.posts %} <li><a href="{{ post.url }}">{{ post.title }}</a></li> {% endfor %} </ul> 

Collections Link

In WordPress, custom post types are useful for managing groups of content. For example, you might use custom post types for testimonials, products or real-estate listings.

Jekyll has this feature and calls it collections20.

The about.html page shows profiles of staff members. We could define the meta data for the staff (name, image, phone number, bio) in the front matter, but then we could only reference it on that page. In the future, we want to use the same data to display information about authors on blog posts. A collection enables us to refer to staff members anywhere on the website.

Configuration of our website lives in _config.yml. Here, we set a new collection:

collections: staff_members: output: false 

Now we add our staff members. Each staff member is represented in a Markdown file stored in a folder with the collection name; for example, _staff_members/jane-doe.md.

We add the meta data in the front matter and the blurb in the body:

--- name: Jane Doe image: "/images/jane.jpeg" phone: "1234567" --- Jane has 19 years of experience in law, and specialises in property and business. 

Similar to posts, we can iterate over the collection in about.html to display each staff member:

--- layout: default --- <ul> {% for member in site.staff_members %} <li> <div><img src="{{ member.image }}" alt="Staff photo for {{ member.name }}"></div> <p>{{ member.name }} - {{ member.phone }}</p> <p>{{ member.content | markdownify }}</p> </li> {% endfor %} </ul> 

Search Link

WordPress has powerful built-in search and even more powerful search plugins.

Jekyll doesn’t have search built in, but there are solutions:

Plugins Link

Plugins are an appealing part of WordPress. It’s easy to load in functionality to get WordPress to do almost anything.

On our Jekyll website, many popular WordPress plugins aren’t necessary:

  • iThemes Security25
    Our Jekyll website is as secure as the web server it’s running on.
  • Backup Guard26
    Our Jekyll website will live in a repository that gives us access to the entire history of changes.
  • WP Super Cache27
    Our Jekyll website is already static.

Other WordPress plugins have third-party equivalents that we can drop into the website:

Some WordPress plugins can be emulated with core Jekyll. Here’s a photo gallery using front matter and Liquid:

--- layout: default images: - image_path: /images/bill.jpg title: Bill - image_path: /images/burt.jpg title: Burt - image_path: /images/gary.jpg title: Gary - image_path: /images/tina.jpg title: Tina - image_path: /images/suzy.jpg title: Suzy --- <ul> {% for image in page.images %} <li><img src="{{ image.image_path }}" alt="{{ image.title }}"/></li> {% endfor %} </ul> 

We just need to add our own JavaScript and CSS to complete it.

Jekyll plugins can emulate the functionality of other WordPress plugins. Keep in mind that Jekyll plugins only run while the website is being generated — they don’t add real-time functionality:

Version Control Link

One of the major benefits of using a static site generator like Jekyll is the entire site and content can live in Git. At a basic level, Git gives you a history of all the changes on the site. For teams, it opens up all sorts of workflows and approval processes.

GitHub has a fantastic interactive tutorial46 for beginners learning Git.

Client Hand-Off Link

That covers the nuts and bolts of creating the website. If you’re curious to see how an entire Jekyll website fits together, have a look at the Justice template47. It’s a free MIT-licensed template for Jekyll. The snippets above are based on this template.

The WordPress CMS is built into the platform, so we would need to set up an account for the client.

With our Jekyll website, we’d link our Git repository to one of the Jekyll GUIs mentioned earlier. One of the nice things about this workflow is that clients changes are committed back to the repository. As developers, we can continue to use local workflows even with non-developers updating the website.

Some Jekyll GUIs offer hosting, while others have a way to output to an Amazon S3 bucket or to GitHub Pages48.

Summary Link

At this point, our Jekyll website is live and editable by the client. If we need to make any changes to the website, we simply push to the repository and it will automatically deploy live.

Your First Jekyll Website Link

Now it’s your turn. Plenty of resources are available to help you build your first Jekyll website:

  • The official Jekyll website49 is a great place to start with in-depth documentation on all of Jekyll’s features.
  • Jekyll.tips50 has a video tutorial series covering core Jekyll topics.
  • Have a look at Jekyll templates on GitHub to see how they’re put together: Frisco51 for marketing websites, Scholar52 for documentation and Urban53 for digital agencies.

If you’re migrating, Jekyll has tools to import posts54 from WordPress and WordPress.com websites. After importing, you’ll need to manually migrate or create the layouts, pages, CSS, JavaScript and other assets for the website.

Wrapping Up Link

The beauty of Jekyll is in its simplicity. While WordPress can match many of the features of Jekyll, it often comes at the cost of complexity through extra plugins or infrastructure.

Ultimately, it’s about finding the tool that works best for you. I’ve found Jekyll to be a fast and efficient way to build websites. I encourage you to try it out and post your experience in the comments.

(al)

Footnotes Link

  1. 1 https://grey-grouse.cloudvent.net/
  2. 2 https://www.smashingmagazine.com/2014/08/build-blog-jekyll-github-pages/
  3. 3 https://www.smashingmagazine.com/2016/02/content-modeling-with-jekyll/
  4. 4 https://www.smashingmagazine.com/2015/11/static-website-generators-jekyll-middleman-roots-hugo-review/
  5. 5 https://www.smashingmagazine.com/2015/11/modern-static-website-generators-next-big-thing/
  6. 6 http://jekyllrb.com/
  7. 7 https://www.atlassian.com/git/tutorials/why-git/git-for-developers
  8. 8 https://versionpress.net/
  9. 9 https://cloudcannon.com/
  10. 10 https://forestry.io/
  11. 11 https://github.com/jekyll/jekyll-admin
  12. 12 https://github.com/netlify/netlify-cms
  13. 13 http://prose.io/
  14. 14 https://www.siteleaf.com/
  15. 15 http://shopify.github.io/liquid/
  16. 16 https://upstatement.com/timber/
  17. 17 https://en.wikipedia.org/wiki/YAML
  18. 18 https://jekyllrb.com/docs/frontmatter/
  19. 19 https://en.wikipedia.org/wiki/Markdown
  20. 20 https://jekyllrb.com/docs/collections/
  21. 21 http://lunrjs.com/
  22. 22 http://jekyll.tips/jekyll-casts/jekyll-search-using-lunr-js/
  23. 23 https://blog.algolia.com/instant-search-blog-documentation-jekyll-plugin/
  24. 24 https://cse.google.com/
  25. 25 https://wordpress.org/plugins/better-wp-security/
  26. 26 https://wordpress.org/plugins/backup/
  27. 27 https://wordpress.org/plugins/wp-super-cache/
  28. 28 https://wordpress.org/plugins/contact-form-7/
  29. 29 http://formspree.io/
  30. 30 https://formkeep.com/
  31. 31 http://www.wufoo.com/
  32. 32 https://wpecommerce.org/
  33. 33 http://snipcart.com/
  34. 34 https://gumroad.com/
  35. 35 https://stripe.com/
  36. 36 https://wordpress.org/plugins/akismet/
  37. 37 https://disqus.com/
  38. 38 https://developers.facebook.com/docs/plugins/comments
  39. 39 http://intensedebate.com/
  40. 40 https://wordpress.org/plugins/one-click-xml-sitemap/
  41. 41 https://github.com/jekyll/jekyll-sitemap
  42. 42 https://github.com/jekyll/jekyll-seo-tag
  43. 43 http://www.seowizard.org
  44. 44 https://wordpress.org/plugins/wpglobus/
  45. 45 https://github.com/vwochnik/jekyll-language-plugin
  46. 46 https://try.github.io/
  47. 47 https://github.com/CloudCannon/justice-jekyll-template
  48. 48 https://pages.github.com/
  49. 49 https://jekyllrb.com/
  50. 50 http://jekyll.tips/
  51. 51 https://github.com/CloudCannon/frisco-jekyll-template
  52. 52 https://github.com/CloudCannon/scholar-jekyll-template
  53. 53 https://github.com/CloudCannon/urban-jekyll-template
  54. 54 https://import.jekyllrb.com/

↑ Back to topTweet itShare on Facebook

Unleashing The Full Potential Of Symbols In Sketch

artificial intelligence 5291510 1920

Unleashing The Full Potential Of Symbols In Sketch

No matter whether you are designing a whole design system or just a couple of screens, symbols in Sketch will help you keep your file organized and will save you a lot of time in the long run. In this article, I’ll share with you a few best practices and tricks to help you unleash symbols’ full potential.

But first, a bit of a backstory. I started using Sketch a few years ago, as a replacement for my favorite design software back then, Fireworks1, which had been discontinued2 by Adobe — leaving a whole generation of designers3 broken-hearted. Since my first days of using Sketch, I was very surprised by how easy and straightforward it is to use. I had, once again, found an application focused on user interface (and icon) design — and nothing else.

The apparent lack of features in Sketch, compared to the alternatives full of menus and stacked panels4 that I was used to, was in fact one of its major advantages and helped me to design faster. Among those few features, symbols were the thing that I used very frequently, and still do, practically every day (yes, even on Sundays… you know, a freelancer’s life).

What are symbols? In a nutshell, symbols enable you to use and reuse an element across a project, keeping a master symbol that automatically updates other instances of the symbol when changes are made to it.

5
Symbols are essential to building a design system formed by elements and components that will be used across all of your project. (Source: “How We’re Using Component-Based Design6”) (View large version7)

This concept is not exactly new (nor is it exclusive to Sketch, to be honest). However, if you design interfaces, then you’ll find it extremely useful, especially when using components as part of a design system8.

In this article, I’ll outline how to make use of symbols in Sketch in order to unleash their full potential, going from the most basic situations to some more advanced use cases. I’ll also include some tips and tricks that I have learned along the way.

Further Reading on SmashingMag: Link

A Brief Introduction To Symbols Link

Before digging deeper, and in case you are new to Sketch, let me give you a short introduction to how symbols work.

Symbols can be made from almost any elements in Sketch: text objects, shapes, bitmap images, even other symbols (we’ll talk about this later). Inside every symbol (double-click a symbol to enter edit mode), you’ll find one main artboard containing the symbol’s layers. This artboard also defines the symbol’s boundaries.

Usually, symbols are created for those elements in an interface that you expect to reuse later on (such as buttons, list items, tabs, etc.) and that will be spread across different screens, pages and artboards in your designs.

Note: For future reference, keep in mind that “copies” of one symbol are called instances.

The best thing about using symbols (instead of grouped, independent and disconnected objects) is that if at some point you decide to change some property in a particular symbol (for example, the color, shape, text size, dimensions or whatever else you want), you’ll just need to edit the symbol’s master once, and this change will be automatically replicated to all of the master’s instances, wherever they are. I don’t know about you, but I find this super-convenient!

Tip 1: Be Organized Link

Just like in life itself, it’s fundamental to keep everything in order. Always design as if someone else will later need to open and work with your design file and understand it without your help! This also applies to the way you name symbols — naming should meet certain criteria.

One recommendation is to use a slash (/) in the symbol’s name. Sketch will automatically create a category with the part before the slash, and will name and place the symbol inside it, using the part of the name following the slash. For example, if you have two symbols named “Button/Primary” and “Button/Secondary,” here is how they will look like when you try to insert them from the toolbar:

13
Naming symbols properly can help you create a neat hierarchy system, which will help you find symbols faster. (View large version14)

You can repeat this many times to have several symbols under the same root, grouped by similar logic, making them easier to find. And if your “tree” grows too big, take a moment to reconsider your naming system and see if there’s any possible way to optimize it and make it more manageable.

Tip 2: Naming Conventions Link

There are many different conventions for how symbols should be named, perhaps one convention for every designer out there. Personally, I prefer not to use names that refer to the visual properties of the elements — for example, “Red Button” would be a bad choice in my opinion because if the color of the button changes later on for some reason, the name of the symbol will become incorrect. Instead, I try to differentiate the symbol’s function and state (such as “Primary/Disabled”).

In any case, just be consistent and find something that works for both you and your team, then stick to it; don’t switch the naming system according to the case! This also applies to layers inside symbols: some designers even use emojis15 to mark which of them are meant to be editable (for example, by adding a pencil emoji to the name). To do this, press Control + Command + Space to open a dialog to select emojis16.

17
Adding an emoji to a layer’s name is an option when you want to highlight its purpose.

Note: Regarding symbols’ names, bear in mind that instances will take their names from the master symbol, but you can change them afterwards to whatever you want. This way, instances of the same symbol can have different names from each other.

Tip 3: An Alternative to the Symbols Page Link

When you create a symbol, Sketch asks whether you want to send it to the symbols page18. My advice is to check this box, even if after a while (and a few symbols later) this dedicated page turns into a mess. (Sketch places one symbol next to the other as they are being created, and when you delete a symbol, you’ll notice the blank space left in its spot.)

Instead, what I do to sort this out is to create my own symbols page (which is just a regular page, which I would usually name “Symbols”) where I can arrange symbol instances in the order I want and, thus, ignore the official symbols page.

19
The symbols page (left) can easily become disorganized, which is why I prefer to have my own separate page (right) where I can organize symbols’ instances in the way I think best. (View large version20)

This way, I can create artboards that follow categories (such as lists, buttons, inputs and so on) and place symbols in a way that I find convenient and that makes sense to me. You’ll still need to invest some time to update this page from time to time, but once it is created, it will make everything much easier and you’ll be able to build a new screen in no time.

Note: If you prefer to use the symbols page instead, there’s the Symbol Organizer plugin21, which could help you keep everything arranged.

Tip 4: Replacing Symbols Link

Replacing an existing symbol with another is easy. Just select the symbol and choose “Replace with” from the contextual menu that appears when you right-click over the symbol instance. Then, select the new symbol that you want to use. Keep in mind that the new symbol will keep the same size and position as its predecessor; you can fix this by selecting “Set to original size” from the same contextual menu.

22
Replacing symbols

Tip 5: Detaching Link

Once you’ve made a symbol, you can detach it to recover the elements that form it as a group. To do this, just select “Detach from symbol” in the same contextual menu that I mentioned earlier.

Tip 6: Exporting Symbols as Assets Link

Symbols, like other elements, can also be exported as bitmap images. To do this, you’ll need to mark elements as exportable. (Select the symbol instance, and then choose “Make Exportable” at the bottom of the Inspector.)

The problem that I found during this process is that if the symbol has some padding (for example, if the shapes inside are smaller than the symbol’s total size), when doing the export, Sketch will omit the blank space and will just create an image with the visible content only.

23
Exporting the symbol directly will create an image that contains only the shapes (left). Make use of slices (right) to match the symbol size before exporting. (View large version24)

One way to work this around is by using a slice25. When creating the slice, place it over the instance and make sure it matches the size of the instance’s boundaries (width and height); then, select the slice and use the exporting options as needed.

Side note: This same trick also applies to other tools, such as Zeplin26.

Further Reading Link

Handling Different Sizes Link

In this world full of screens with multiple sizes and aspect ratios, it’s important to make sure your design adapts to many different scenarios. This is easier to accomplish if you don’t have to design everything from scratch every time, by reusing elements (or symbols, as I’m sure you’ve already guessed).

29
A variety of resizing options are available in Sketch. These are very useful when you are looking to adapt your symbols to different dimensions.

This is where the resizing options in symbols come in handy, helping you to use the same element with different widths and heights with no hassle: If you resize just one instance by selecting it, this won’t affect the other instances. (But remember that resizing options are applied to individual layers inside the master symbol, not to the instance itself. So, even while you can adjust sizes individually from instance to instance, elements inside will always maintain the same behavior.)

Note: The options outlined below apply not only to symbols, but to groups as well. Behaviors are not always predictable, so chances are that you’ll have to play around and explore a bit before finding what you need, combining one or two different settings in most cases.

Stretch Link

30
In this example you can see how the yellow shape will remain one third of the total width of the symbol, no matter what the total width of the symbol is.

When the Stretch option is used, a shape that has specified, let’s say, 50% of the symbol’s total width will keep this same relationship when the instance is extended vertically or horizontally. This is the default behavior.

Pin to Corner Link

31
The yellow shape has the “Pin to Corner” option applied to it, so it sticks to the closest corner.

“Pin to Corner” will (as the name suggests) pin an element to the nearest corner, and the element will not resize, keeping the same distance to this corner. Keep in mind that if the object is centered (with equal spacing from both sides), it won’t know which one is the nearest corner, so it’ll stay in the middle.

Resize Object Link

32
The yellow shape has the “Resize Object” option applied to it. You can better understand what is happening by also looking at the pink squares, which are for reference only.

When “Resize Object” is used, elements will grow while keeping an equal (or fixed) spacing from the sides.

Float in Place Link

33
With this option, the element won’t resize, keeping the relative position to the boundaries of the symbol.

“Float in Place” will make an object stay the same size and will keep its relative position to the boundaries of the symbol.

Tip 1: Back to the Original Size Link

If you have resized your symbol but aren’t satisfied with the result, you can always go back to the beginning by choosing “Set to original size” from the contextual menu.

Tip 2: Boundaries Link

Keep in mind that symbols have dedicated artboards, and these will define the symbols’ boundaries (even when shapes inside overflow on them). You can make the symbol’s artboard the same size as of its contents by selecting it and choosing “Resize to fit” from the Inspector.

Tip 3: Using Characters and Operators Link

In the width and height input fields in the Inspector, you can use operators to change values. For instance, you can use 100*2 to set an element’s dimensions to 200 pixels. Other operators are + (add), - (subtract) and / (divide).

Besides mathematical operators, in the same input fields you can also use L to scale an object from the left (this is the default), R to scale it from the right, T to scale it from the top (this is the default), B to scale it from the bottom, and C and M to scale it from the center or middle.

34
When you resize a rectangle using its upper-right corner as an anchor, the shape will grow out of its left and bottom sides.

For example, if you have a shape that has a width of 200 pixels and want to resize it so that it scales from the right to the left side, you can use something like 300r in the width input field.

Further Reading Link

  • Sketch 39 Resizing: Cheat Sheet35” Peter Nowell

    This article is a good reference for understanding the differences in resizing. It also includes some other tips and tricks, so give it a go!

Nested Symbols Link

What could be better than one symbol? Perhaps a symbol with another one inside it!

This feature is kind of new in Sketch, and it gives you a lot of possibilities when combining symbols together. You can place one symbol on top of another, select both, and then create a new symbol that contains the two instances. You can repeat this as much as you’d like. Be moderate, though, or else you’ll find yourself digging into levels and levels of nested symbols, one inside another. This could make maintenance much harder and could also be a symptom of bigger organizational problems.

Nesting symbols can be especially useful when you need to create variations of one symbol. For example, you could follow a process like this:

  1. Pick up one symbol that will serve as a base. (this symbol will remain the same in all cases.)
  2. Overlap it with other symbols (such as icons or badges), which could be there or not, depending on the case.
  3. Finally, create another symbol with the resulting design.

In the image below, you can see that all rows share the same characteristics (they have the same size, text properties and amount of padding on the left), so I created a base symbol that contains only these elements (i.e. elements that will be shared with the other symbols). Using this symbol as a starting point, I then created some overlapping elements that are different, saving the result in each case as a different symbol; so, all of the symbols under “Variations” are actually different symbols.

36
An example of different symbols created from a common base, with variations in each case.

But you don’t — necessarily — need to create a new symbol for every state of the row. There may be a simpler way: using overrides.

Nested Overrides Link

If you had to create a lot of different symbols just because one part of their content changes, you’d probably go nuts. One of the main purposes of symbols is precisely to have to design as little as possible and to have fewer elements — and, therefore, more control over them. Enter nested overrides!

37
This navigation bar is a symbol that contains the inactive tabs (which are symbols as well). Active tabs are symbols created separately; they override the inactive tabs when necessary.

One practical example of this workflow could be designing a tab bar with different states. In this case, the main symbol with the inactive tabs would act as the base, and then there would be a different symbol for each one of the highlighted tabs. Just choose the one that you want from the “Overrides” options in the Inspector.

Note: For this technique to work, keep in mind that the inactive tabs inside the main symbol (the navigation bar) need to be symbols as well. Also, be sure that all symbols (both inactive and active ones) have the exact same dimensions (width, height). Otherwise, they won’t appear as available options in the “Overrides” dropdown menu.

Let’s look at another use case. If you have multiple buttons in a design but with different text labels on them, then the Overrides option will enable you to change the text value (not the font family or font size — you have to modify those inside the symbol itself, when editing the symbol master), without having to create a new symbol each time. This is as easy to do as selecting the instance and changing the text content in the Inspector.

Overrides apply not only to text; you can also use them for bitmap images and even for other symbols, as mentioned before. This way, you can have several instances of a symbol, with a different image in each one of them — and all of this without having to modify the symbol’s master.

38
Let me show you how overriding images works with something that I usually do when designing.

There are cases when I don’t want to have any particular image as part of a symbol’s master. So, what I usually do is to create an empty PNG file with no visible content, create a shape, and use this image as a pattern fill (you can find this option in the “Fill Options” when selecting a shape). Then, when doing the symbol overriding, I just replace this transparent image with the one that I want in each case!

To get the most out of this practice, I also use a layering system with an icon or element that acts as a placeholder underneath the image and that will be visible only if I keep the original transparent bitmap. One benefit of doing this is that I can simulate this empty state that will appear when images are loading in the finished product, something that I consider necessary to design anyway.

Tip 1: Names and Layer Order Link

One of the reasons why being organized is a good idea is because the way you name and order layers will affect the way they are displayed in the “Overrides” panel. The labels to the left of the input fields in the Inspector will respect the name and order you’ve previously defined inside the symbol itself, so you’d better pay attention to this order if you want to have a more efficient workflow.

Tip 2: Mind the Size Link

You can replace a nested symbol with another symbol only if the new symbol has the exact same width and height as the current element.

Tip 3: Displacing Elements Depending on Text Length Link

When changing the text’s value in the Overrides options, you can make an element move as needed when the one to its left is longer (see the following illustration).

39
Top (first field): This shows the original symbol. Bottom (second field): This illustrates how the “Optional” label moves to the right because of the previous label’s length (in this case, “Phone Number”).

The secondary text or shape necessarily needs to be to the right of the text for this to work. Also, both elements should have no more than 20 pixels of distance between them (see the “Further Reading” below).

Tip 4: Avoiding Overrides Link

A symbol can look a bit messy because of the options in the Overrides section. If you don’t want an element inside it to be able to be overridden, just lock or hide this layer and it won’t appear in the list.

Tip 5: Hiding Nested Symbols Link

Just select “None” from the Overrides section to hide a nested symbol. Of course, it will only be invisible in that particular instance.

Tip 6: Hiding Text Link

There’s one way to quickly make a text element disappear in an instance, by using overrides. To do this, just set the text value to a blank space, pressing the space bar and the return key in the Overrides options.

Tip 7: Recovering the Original Image Link

If you have bitmap images inside a symbol, they can be changed by others using the options in the Overrides section. It’s also possible to recover the original image (the one that forms part of the editable symbol) by choosing “Remove image override” — just right-click over the image box next to “Choose Image” in the Inspector.

Further Reading (and a Video) Link

Plugins That Play Well With Symbols Link

One good thing about Sketch is that when it falls short of a feature, there’s usually a plugin to make up for it. And some of them work especially well with symbols, making them even more powerful! Some of these plugins have been mentioned, but in case you missed any of them, here’s a list with some additions.

50
Sketch Runner lets you quickly insert symbols by navigating a list, and it also shows a preview in the right panel. (View large version51)

Sketch Runner Link

Among its many other features, the Sketch Runner52 plugin will help you easily insert symbols in a document using just a combination of keys. The “go to” option is very useful for jumping right to a particular symbol — very useful if your project has a lot of them and if it’s difficult to find symbols using other means.

InVision Craft Library Link

If you are working with a team, InVision Craft Library53 will make it easy to create a shared library with assets that everybody can use, allowing you to sync changes when you need to update a symbol, so that you are always sure you’re using the symbols’s latest version.

Automate Link

Automate54 is very powerful and will likely make your work more efficient. Options for managing symbols include ones to remove unused symbols, to select all instances of a symbol, and much more.

Symbol Instance Renamer Link

Symbol Instance Renamer55 renames all instances to match the name of their master symbols.

Symbol Organizer Link

With Symbol Organizer56, organize your symbols page alphabetically (including the layers list) and into separate groups determined by your symbol names.

Auto Layout Link

Auto Layout57 integrates seamlessly in Sketch and enables defining and viewing different iPhone and iPad sizes including portrait and landscape. It also supports more advanced features, such as stacks (a special type of group that defines the layouts of its child layers), and presets for both Android and iOS. Look at their “Examples” page58 for more information.

Note: These are only some of the plugins that I think might be most helpful to you, but there are many others. To know more, just visit Sketch’s official plugin page59 or the Sketch App Sources60 website regularly.

Final Thoughts Link

Sketch symbols are constantly evolving, so we can expect further improvements that will make them even more valuable and relevant. However, if I had to name just one thing that I would like them to have, that would be the possibility to have shared symbols’ libraries, something like Figma is doing61. This could be extremely useful, especially for team work, when several designers working on the same project need to pick elements from a primary, always up-to-date document stored in the cloud.

(Note: Regarding this feature, I’m aware that Sketch’s team is working on it, so hopefully we’ll see it soon. The more open format in version 4362 is probably laying the groundwork for this feature. In any case, I’m looking forward to it, because this could be a game-changer in many designer workflows.)

Truth be told, there are currently some plugins that help you accomplish more or less the same behavior mentioned above, but I always find it more reliable when they are made a part of Sketch’s core functionality — which ensures that the feature will keep working when the software is updated to the next version.

I’m aware that there are many more techniques and tricks. The way one works tends to be kind of personal sometimes, and there’s no single right way to do something. Here, I’ve shared the techniques that I think are reliable, interesting and don’t require much hacking. That’s why some techniques were left out of this article.

I hope this was a useful read! If it was, then symbols will probably become the backbone of your designs, and you’ll use them quite often. Feel free to share your thoughts and other tips and tricks in the comments below. You can also always reach me on Twitter63 if you need help!

(mb, al)

Footnotes Link

  1. 1 https://www.smashingmagazine.com/category/fireworks/
  2. 2 https://www.smashingmagazine.com/2013/12/present-future-adobe-fireworks/
  3. 3 http://blogs.adobe.com/fireworks/2013/05/the-future-of-adobe-fireworks.html
  4. 4 https://twitter.com/phlntn/status/715367818254921730
  5. 5 https://www.smashingmagazine.com/wp-content/uploads/2017/04/system-large-opt.png
  6. 6 https://medium.com/@lewisplushumphreys/how-were-using-component-based-design-5f9e3176babb
  7. 7 https://www.smashingmagazine.com/wp-content/uploads/2017/04/system-large-opt.png
  8. 8 https://medium.freecodecamp.com/how-to-construct-a-design-system-864adbf2a117
  9. 9 https://www.smashingmagazine.com/2015/04/using-sketch-for-responsive-web-design-case-study/
  10. 10 https://www.smashingmagazine.com/2009/10/the-ultimate-round-up-of-print-design-tutorials/
  11. 11 https://www.smashingmagazine.com/responsive-web-design-guidelines-tutorials/
  12. 12 https://www.smashingmagazine.com/2016/04/exploring-a-new-illustration-ui-design-app-gravit/
  13. 13 https://www.smashingmagazine.com/wp-content/uploads/2017/04/buttons-large-opt.png
  14. 14 https://www.smashingmagazine.com/wp-content/uploads/2017/04/buttons-large-opt.png
  15. 15 http://emojipedia.org/
  16. 16 http://www.imore.com/how-to-use-emoji-on-your-mac
  17. 17 https://www.smashingmagazine.com/wp-content/uploads/2017/04/emojis-preview-opt.png
  18. 18 http://www.sketchtips.info/articles/the-power-of-symbols
  19. 19 https://www.smashingmagazine.com/wp-content/uploads/2017/04/page-large-opt.png
  20. 20 https://www.smashingmagazine.com/wp-content/uploads/2017/04/page-large-opt.png
  21. 21 https://github.com/sonburn/symbol-organizer
  22. 22 https://www.smashingmagazine.com/wp-content/uploads/2017/04/replace-animated.gif
  23. 23 https://www.smashingmagazine.com/wp-content/uploads/2017/04/slice-large.png
  24. 24 https://www.smashingmagazine.com/wp-content/uploads/2017/04/slice-large.png
  25. 25 https://www.sketchapp.com/learn/documentation/exporting/slices/
  26. 26 https://zeplin.io/
  27. 27 https://medium.com/@lloyd/sketch-symbols-best-practices-now-that-nested-overrides-are-a-thing-9b651d3fe1a4
  28. 28 https://twitter.com/Lloyd
  29. 29 https://www.smashingmagazine.com/wp-content/uploads/2017/04/general-animated.gif
  30. 30 https://www.smashingmagazine.com/wp-content/uploads/2017/04/stretch-animated.gif
  31. 31 https://www.smashingmagazine.com/wp-content/uploads/2017/04/pin-to-corner-animated.gif
  32. 32 https://www.smashingmagazine.com/wp-content/uploads/2017/04/resize-animated-1.gif
  33. 33 https://www.smashingmagazine.com/wp-content/uploads/2017/04/float-in-place-animated.gif
  34. 34 https://www.smashingmagazine.com/wp-content/uploads/2017/04/stretch-right-animated.gif
  35. 35 https://medium.com/sketch-app-sources/sketch-39-resizing-cheat-sheet-feec0450e7e2
  36. 36 https://www.smashingmagazine.com/wp-content/uploads/2017/04/nested-preview-opt.png
  37. 37 https://www.smashingmagazine.com/wp-content/uploads/2017/04/overrides-01-animated.gif
  38. 38 https://www.smashingmagazine.com/wp-content/uploads/2017/04/placeholder-animated.gif
  39. 39 https://www.smashingmagazine.com/wp-content/uploads/2017/04/input-preview-opt.png
  40. 40 https://medium.com/sketch-app-sources/hacking-the-button-in-sketch-5cbce8526b3f
  41. 41 https://medium.com/sketch-app-sources/hacking-the-button-in-sketch-5cbce8526b3f
  42. 42 https://medium.com/@yarontm/adaptive-text-elements-in-sketch-fe5d2a36c3d5
  43. 43 https://twitter.com/YaronTm
  44. 44 https://medium.com/@FreeAndWilling/sketch-tint-icons-using-nested-symbols-2d52867e0d29
  45. 45 https://twitter.com/fbmore
  46. 46 https://medium.com/ux-power-tools/this-is-without-a-doubt-the-coolest-sketch-technique-youll-see-all-day-ddefa65ea959
  47. 47 https://twitter.com/thejmoore
  48. 48 https://www.youtube.com/watch?v=_bjqVF7Fvg4
  49. 49 https://twitter.com/pablostanley
  50. 50 https://www.smashingmagazine.com/wp-content/uploads/2017/04/plugins-large-opt.png
  51. 51 https://www.smashingmagazine.com/wp-content/uploads/2017/04/plugins-large-opt.png
  52. 52 http://sketchrunner.com/
  53. 53 https://support.invisionapp.com/hc/en-us/articles/208434046-Craft-Introduction-to-the-Library-plugin
  54. 54 https://github.com/ashung/automate-sketch
  55. 55 https://github.com/sonburn/symbol-instance-renamer
  56. 56 https://github.com/sonburn/symbol-organizer
  57. 57 https://animaapp.github.io/Auto-Layout/
  58. 58 https://animaapp.github.io/docs/v1/guide/13-examples.html
  59. 59 https://www.sketchapp.com/extensions/plugins/
  60. 60 https://www.sketchappsources.com/plugins.html
  61. 61 https://medium.com/figma-design/team-libraries-in-figma-409fa5e20f7
  62. 62 https://twitter.com/NunoMRocha/status/847196484646916097
  63. 63 http://www.twitter.com/millonestarde

↑ Back to topTweet itShare on Facebook

It’s Time To Start Using CSS Custom Properties

artificial intelligence 5291510 1920

It’s Time To Start Using CSS Custom Properties

Today, CSS preprocessors are a standard for web development. One of the main advantages of preprocessors is that they enable you to use variables. This helps you to avoid copying and pasting code, and it simplifies development and refactoring.

We use preprocessors to store colors, font preferences, layout details — mostly everything we use in CSS.

But preprocessor variables have some limitations:

  • You cannot change them dynamically.
  • They are not aware of the DOM’s structure.
  • They cannot be read or changed from JavaScript.

As a silver bullet for these and other problems, the community invented CSS custom properties. Essentially, these look and work like CSS variables, and the way they work is reflected in their name.

Custom properties are opening new horizons for web development.

Further Reading on SmashingMag: Link

Syntax To Declare And Use Custom Properties Link

The usual problem when you start with a new preprocessor or framework is that you have to learn a new syntax.

Each preprocessor requires a different way of declaring variables. Usually, it starts with a reserved symbol — for example, $ in Sass and @ in LESS.

CSS custom properties have gone the same way and use -- to introduce a declaration. But the good thing here is that you can learn this syntax once and reuse it across browsers!

You may ask, “Why not reuse an existing syntax?”

There is a reason5. In short, it’s to provide a way for custom properties to be used in any preprocessor. This way, we can provide and use custom properties, and our preprocessor will not compile them, so the properties will go directly to the outputted CSS. And, you can reuse preprocessor variables in the native ones, but I will describe that later.

(Regarding the name: Because their ideas and purposes are very similar, sometimes custom properties are called the CSS variables, although the correct name is CSS custom properties, and reading further, you will understand why this name describes them best.)

So, to declare a variable instead of a usual CSS property such as color or padding, just provide a custom-named property that starts with --:

.box{ --box-color: #4d4e53; --box-padding: 0 10px; }

The value of a property may be any valid CSS value: a color, a string, a layout value, even an expression.

Here are examples of valid custom properties:

:root{ --main-color: #4d4e53; --main-bg: rgb(255, 255, 255); --logo-border-color: rebeccapurple; --header-height: 68px; --content-padding: 10px 20px; --base-line-height: 1.428571429; --transition-duration: .35s; --external-link: "external link"; --margin-top: calc(2vh + 20px); /* Valid CSS custom properties can be reused later in, say, JavaScript. */ --foo: if(x > 5) this.width = 10; } 

In case you are not sure what :root6 matches, in HTML it’s the same as html but with a higher specificity.

As with other CSS properties, custom ones cascade in the same way and are dynamic. This means they can be changed at any moment and the change is processed accordingly by the browser.

To use a variable, you have to use the var() CSS function and provide the name of the property inside:

.box{ --box-color:#4d4e53; --box-padding: 0 10px; padding: var(--box-padding); } .box div{ color: var(--box-color); } 

Declaration and Use Cases Link

The var() function is a handy way to provide a default value. You might do this if you are not sure whether a custom property has been defined and want to provide a value to be used as a fallback. This can be done easily by passing the second parameter to the function:

.box{ --box-color:#4d4e53; --box-padding: 0 10px; /* 10px is used because --box-margin is not defined. */ margin: var(--box-margin, 10px); } 

As you might expect, you can reuse other variables to declare new ones:

.box{ /* The --main-padding variable is used if --box-padding is not defined. */ padding: var(--box-padding, var(--main-padding)); --box-text: 'This is my box'; /* Equal to --box-highlight-text:'This is my box with highlight'; */ --box-highlight-text: var(--box-text)' with highlight'; } 

Operations: +, -, *, / Link

As we got accustomed to with preprocessors and other languages, we want to be able to use basic operators when working with variables. For this, CSS provides a calc() function, which makes the browser recalculate an expression after any change has been made to the value of a custom property:

:root{ --indent-size: 10px; --indent-xl: calc(2*var(--indent-size)); --indent-l: calc(var(--indent-size) + 2px); --indent-s: calc(var(--indent-size) - 2px); --indent-xs: calc(var(--indent-size)/2); } 

A problem awaits if you try to use a unit-less value. Again, calc() is your friend, because without it, it won’t work:

:root{ --spacer: 10; } .box{ padding: var(--spacer)px 0; /* DOESN'T work */ padding: calc(var(--spacer)*1px) 0; /* WORKS */ } 

Scope And Inheritance Link

Before talking about CSS custom property scopes, let’s recall JavaScript and preprocessor scopes, to better understand the differences.

We know that with, for example, JavaScript variables (var), a scope is limited to the functions.

We have a similar situation with let and const, but they are block-scope local variables.

A closure in JavaScript is a function that has access to the outer (enclosing) function’s variables — the scope chain. The closure has three scope chains, and it has access to the following:

  • its own scope (i.e. variables defined between its braces),
  • the outer function’s variables,
  • the global variables.
7
(View large version8)

The story with preprocessors is similar. Let’s use Sass as an example because it’s probably the most popular preprocessor today.

With Sass, we have two types of variables: local and global.

A global variable can be declared outside of any selector or construction (for example, as a mixin). Otherwise, the variable would be local.

Any nested blocks of code can access the enclosing variables (as in JavaScript).

9
(View large version10)

This means that, in Sass, the variable’s scopes fully depend on the code’s structure.

However, CSS custom properties are inherited by default, and like other CSS properties, they cascade.

You also cannot have a global variable that declares a custom property outside of a selector — that’s not valid CSS. The global scope for CSS custom properties is actually the :root scope, whereupon the property is available globally.

Let’s use our syntax knowledge and adapt the Sass example to HTML and CSS. We’ll create a demo using native CSS custom properties. First, the HTML:

global <div> enclosing <div> closure </div> </div> 

And here is the CSS:

:root { --globalVar: 10px; } .enclosing { --enclosingVar: 20px; } .enclosing .closure { --closureVar: 30px; font-size: calc(var(--closureVar) + var(--enclosingVar) + var(--globalVar)); /* 60px for now */ } 

See the Pen css-custom-properties-time-to-start-using 111 by Serg Hospodarets (@malyw4035302421181512) on CodePen4136312522191613.

Changes to Custom Properties Are Immediately Applied to All Instances Link

So far, we haven’t seen how this is any different from Sass variables. However, let’s reassign the variable after its usage:

In the case of Sass, this has no effect:

.closure { $closureVar: 30px; // local variable font-size: $closureVar +$enclosingVar+ $globalVar; // 60px, $closureVar: 30px is used $closureVar: 50px; // local variable } 

See the Pen css-custom-properties-time-to-start-using 314 by Serg Hospodarets (@malyw4035302421181512) on CodePen4136312522191613.

But in CSS, the calculated value is changed, because the font-size value is recalculated from the changed --closureVar value:

.enclosing .closure { --closureVar: 30px; font-size: calc(var(--closureVar) + var(--enclosingVar) + var(--globalVar)); /* 80px for now, --closureVar: 50px is used */ --closureVar: 50px; } 

See the Pen css-custom-properties-time-to-start-using 217 by Serg Hospodarets (@malyw4035302421181512) on CodePen4136312522191613.

That’s the first huge difference: If you reassign a custom property’s value, the browser will recalculate all variables and calc() expressions where it’s applied.

Preprocessors Are Not Aware of the DOM’s Structure Link

Suppose we wanted to use the default font-size for the block, except where the highlighted class is present.

Here is the HTML:

<div> default </div> <div> default highlighted </div> 

Let’s do this using CSS custom properties:

.highlighted { --highlighted-size: 30px; } .default { --default-size: 10px; /* Use default-size, except when highlighted-size is provided. */ font-size: var(--highlighted-size, var(--default-size)); } 

Because the second HTML element with the default class carries the highlighted class, properties from the highlighted class will be applied to that element.

In this case, it means that --highlighted-size: 30px; will be applied, which in turn will make the font-size property being assigned use the --highlighted-size.

Everything is straightforward and works:

See the Pen css-custom-properties-time-to-start-using 420 by Serg Hospodarets (@malyw4035302421181512) on CodePen4136312522191613.

Now, let’s try to achieve the same thing using Sass:

.highlighted { $highlighted-size: 30px; } .default { $default-size: 10px; /* Use default-size, except when highlighted-size is provided. */ @if variable-exists(highlighted-size) { font-size: $highlighted-size; } @else { font-size: $default-size; } } 

The result shows that the default size is applied to both:

See the Pen css-custom-properties-time-to-start-using 523 by Serg Hospodarets (@malyw4035302421181512) on CodePen4136312522191613.

This happens because all Sass calculations and processing happen at compilation time, and of course, it doesn’t know anything about the DOM’s structure, relying fully on the code’s structure.

As you can see, custom properties have the advantages of variables scoping and add the usual cascading of CSS properties, being aware of the DOM’s structure and following the same rules as other CSS properties.

The second takeaway is that CSS custom properties are aware of the DOM’s structure and are dynamic.

CSS-Wide Keywords And The all Property Link

CSS custom properties are subject to the same rules as the usual CSS custom properties. This means you can assign any of the common CSS keywords to them:

  • inherit

    This CSS keyword applies the value of the element’s parent.
  • initial

    This applies the initial value as defined in the CSS specification (an empty value, or nothing in some cases of CSS custom properties).
  • unset

    This applies the inherited value if a property is normally inherited (as in the case of custom properties) or the initial value if the property is normally not inherited.
  • revert

    This resets the property to the default value established by the user agent’s style sheet (an empty value in the case of CSS custom properties).

Here is an example:

.common-values{ --border: inherit; --bgcolor: initial; --padding: unset; --animation: revert; } 

Let’s consider another case. Suppose you want to build a component and want to be sure that no other styles or custom properties are applied to it inadvertently (a modular CSS solution would usually be used for styles in such a case).

But now there is another way: to use the all CSS property26. This shorthand resets all CSS properties.

Together with CSS keywords, we can do the following:

.my-wonderful-clean-component{ all: initial; } 

This reset all styles for our component.

Unfortunately, the all keyword doesn’t reset custom properties27. There is an ongoing discussion about whether to add the -- prefix28, which would reset all CSS custom properties.

So, in future, a full reset might be done like this:

.my-wonderful-clean-component{ --: initial; /* reset all CSS custom properties */ all: initial; /* reset all other CSS styles */ } 

CSS Custom Properties Use Cases Link

There are many uses of custom properties. I will show the most interesting of them.

Emulate Non-Existent CSS Rules Link

The name of these CSS variables is “custom properties,” so why not to use them to emulate non-existent properties?

There are many of them: translateX/Y/Z, background-repeat-x/y (still not cross-browser compatible), box-shadow-color.

Let’s try to make the last one work. In our example, let’s change the box-shadow’s color on hover. We just want to follow the DRY rule (don’t repeat yourself), so instead of repeating box-shadow’s entire value in the :hover section, we’ll just change its color. Custom properties to the rescue:

.test { --box-shadow-color: yellow; box-shadow: 0 0 30px var(--box-shadow-color); } .test:hover { --box-shadow-color: orange; /* Instead of: box-shadow: 0 0 30px orange; */ } 

See the Pen Emulating “box-shadow-color” CSS property using CSS Custom Properties29 by Serg Hospodarets (@malyw4035302421181512) on CodePen4136312522191613.

Color Themes Link

One of the most common use cases of custom properties is for color themes in applications. Custom properties were created to solve just this kind of problem. So, let’s provide a simple color theme for a component (the same steps could be followed for an application).

Here is the code for our button component32:

.btn { background-image: linear-gradient(to bottom, #3498db, #2980b9); text-shadow: 1px 1px 3px #777; box-shadow: 0px 1px 3px #777; border-radius: 28px; color: #ffffff; padding: 10px 20px 10px 20px; } 

Let’s assume we want to invert the color theme.

The first step would be to extend all of the color variables to CSS custom properties and rewrite our component. So, the result would be the same33:

.btn { --shadow-color: #777; --gradient-from-color: #3498db; --gradient-to-color: #2980b9; --color: #ffffff; background-image: linear-gradient( to bottom, var(--gradient-from-color), var(--gradient-to-color) ); text-shadow: 1px 1px 3px var(--shadow-color); box-shadow: 0px 1px 3px var(--shadow-color); border-radius: 28px; color: var(--color); padding: 10px 20px 10px 20px; } 

This has everything we need. With it, we can override the color variables to the inverted values and apply them when needed. We could, for example, add the global inverted HTML class (to, say, the body element) and change the colors when it’s applied:

body.inverted .btn{ --shadow-color: #888888; --gradient-from-color: #CB6724; --gradient-to-color: #D67F46; --color: #000000; } 

Below is a demo in which you can click a button to add and remove a global class:

See the Pen css-custom-properties-time-to-start-using 934 by Serg Hospodarets (@malyw4035302421181512) on CodePen4136312522191613.

This behavior cannot be achieved in a CSS preprocessor without the overhead of duplicating code. With a preprocessor, you would always need to override the actual values and rules, which always results in additional CSS.

With CSS custom properties, the solution is as clean as possible, and copying and pasting is avoided, because only the values of the variables are redefined.

Using Custom Properties With JavaScript Link

Previously, to send data from CSS to JavaScript, we often had to resort to tricks37, writing CSS values via plain JSON in the CSS output and then reading it from the JavaScript.

Now, we can easily interact with CSS variables from JavaScript, reading and writing to them using the well-known .getPropertyValue() and .setProperty() methods, which are used for the usual CSS properties:

/** * Gives a CSS custom property value applied at the element * element {Element} * varName {String} without '--' * * For example: * readCssVar(document.querySelector('.box'), 'color'); */ function readCssVar(element, varName){ const elementStyles = getComputedStyle(element); return elementStyles.getPropertyValue(`--${varName}`).trim(); } /** * Writes a CSS custom property value at the element * element {Element} * varName {String} without '--' * * For example: * readCssVar(document.querySelector('.box'), 'color', 'white'); */ function writeCssVar(element, varName, value){ return element.style.setProperty(`--${varName}`, value); } 

Let’s assume we have a list of media-query values:

.breakpoints-data { --phone: 480px; --tablet: 800px; } 

Because we only want to reuse them in JavaScript — for example, in Window.matchMedia()38 — we can easily get them from CSS:

const breakpointsData = document.querySelector('.breakpoints-data'); // GET const phoneBreakpoint = getComputedStyle(breakpointsData) .getPropertyValue('--phone'); 

To show how to assign custom properties from JavaScript, I’ve created an interactive 3D CSS cube demo that responds to user actions.

It’s not very hard. We just need to add a simple background, and then place five cube faces with the relevant values for the transform property: translateZ(), translateY(), rotateX() and rotateY().

To provide the right perspective, I added the following to the page wrapper:

#world{ --translateZ:0; --rotateX:65; --rotateY:0; transform-style:preserve-3d; transform: translateZ(calc(var(--translateZ) * 1px)) rotateX(calc(var(--rotateX) * 1deg)) rotateY(calc(var(--rotateY) * 1deg)); } 

The only thing missing is the interactivity. The demo should change the X and Y viewing angles (--rotateX and --rotateY) when the mouse moves and should zoom in and out when the mouse scrolls (--translateZ).

Here is the JavaScript that does the trick:

// Events onMouseMove(e) { this.worldXAngle = (.5 - (e.clientY / window.innerHeight)) * 180; this.worldYAngle = -(.5 - (e.clientX / window.innerWidth)) * 180; this.updateView(); }; onMouseWheel(e) { /*…*/ this.worldZ += delta * 5; this.updateView(); }; // JavaScript -> CSS updateView() { this.worldEl.style.setProperty('--translateZ', this.worldZ); this.worldEl.style.setProperty('--rotateX', this.worldXAngle); this.worldEl.style.setProperty('--rotateY', this.worldYAngle); }; 

Now, when the user moves their mouse, the demo changes the view. You can check this by moving your mouse and using mouse wheel to zoom in and out:

See the Pen css-custom-properties-time-to-start-using 1039 by Serg Hospodarets (@malyw4035302421181512) on CodePen4136312522191613.

Essentially, we’ve just changed the CSS custom properties’ values. Everything else (the rotating and zooming in and out) is done by CSS.

Tip: One of the easiest ways to debug a CSS custom property value is just to show its contents in CSS generated content (which works in simple cases, such as with strings), so that the browser will automatically show the current applied value:

body:after { content: '--screen-category : 'var(--screen-category); } 

You can check it in the plain CSS demo42 (no HTML or JavaScript). (Resize the window to see the browser reflect the changed CSS custom property value automatically.)

Browser Support Link

CSS custom properties are supported in all major browsers43:

44
(View large version45)

This means that, you can start using them natively.

If you need to support older browsers, you can learn the syntax and usage examples and consider possible ways of switching or using CSS and preprocessor variables in parallel.

Of course, we need to be able to detect support in both CSS and JavaScript in order to provide fallbacks or enhancements.

This is quite easy. For CSS, you can use a @supports condition46 with a dummy feature query:

@supports ( (--a: 0)) { /* supported */ } @supports ( not (--a: 0)) { /* not supported */ } 

In JavaScript, you can use the same dummy custom property with the CSS.supports() static method:

const isSupported = window.CSS && window.CSS.supports && window.CSS.supports('--a', 0); if (isSupported) { /* supported */ } else { /* not supported */ } 

As we saw, CSS custom properties are still not available in every browser. Knowing this, you can progressively enhance your application by checking if they are supported.

For instance, you could generate two main CSS files: one with CSS custom properties and a second without them, in which the properties are inlined (we will discuss ways to do this shortly).

Load the second one by default. Then, just do a check in JavaScript and switch to the enhanced version if custom properties are supported:

<!-- HTML --> <link href="without-css-custom-properties.css" rel="stylesheet" type="text/css" media="all" /> 
// JavaScript if(isSupported){ removeCss('without-css-custom-properties.css'); loadCss('css-custom-properties.css'); // + conditionally apply some application enhancements // using the custom properties } 

This is just an example. As you’ll see below, there are better options.

How To Start Using Them Link

According to a recent survey47, Sass continues to be the preprocessor of choice for the development community.

So, let’s consider ways to start using CSS custom properties or to prepare for them using Sass.

We have a few options.

1. Manually Check in the Code for Support Link

One advantage of this method of manually checking in the code whether custom properties are supported is that it works and we can do it right now (don’t forget that we have switched to Sass):

$color: red; :root { --color: red; } .box { @supports ( (--a: 0)) { color: var(--color); } @supports ( not (--a: 0)) { color: $color; } } 

This method does have many cons, not least of which are that the code gets complicated, and copying and pasting become quite hard to maintain.

2. Use a Plugin That Automatically Processes the Resulting CSS Link

The PostCSS ecosystem provides dozens of plugins today. A couple of them process custom properties (inline values) in the resulting CSS output and make them work, assuming you provide only global variables (i.e. you only declare or change CSS custom properties inside the :root selector(s)), so their values can be easily inlined.

An example is postcss-custom-properties48.

This plugin offers several pros: It makes the syntax work; it is compatible with all of PostCSS’ infrastructure; and it doesn’t require much configuration.

There are cons, however. The plugin requires you to use CSS custom properties, so you don’t have a path to prepare your project for a switch from Sass variables. Also, you won’t have much control over the transformation, because it’s done after the Sass is compiled to CSS. Finally, the plugin doesn’t provide much debugging information.

3. css-vars Mixin49Link

I started using CSS custom properties in most of my projects and have tried many strategies:

  • Switch from Sass to PostCSS with cssnext50.
  • Switch from Sass variables to pure CSS custom properties.
  • Use CSS variables in Sass to detect whether they are supported.

As a result of that experience, I started looking for a solution that would satisfy my criteria:

  • It should be easy to start using with Sass.
  • It should be straightforward to use, and the syntax must be as close to native CSS custom properties as possible.
  • Switching the CSS output from the inlined values to the CSS variables should be easy.
  • A team member who is familiar with CSS custom properties would be able to use the solution.
  • There should be a way to have debugging information about edge cases in the usage of variables.

As a result, I created css-vars, a Sass mixin that you can find on Github51. Using it, you can sort of start using CSS custom properties syntax.

Using css-vars Mixin Link

To declare variable(s), use the mixin as follows:

$white-color: #fff; $base-font-size: 10px; @include css-vars(( --main-color: #000, --main-bg: $white-color, --main-font-size: 1.5*$base-font-size, --padding-top: calc(2vh + 20px) )); 

To use these variables, use the var() function:

body { color: var(--main-color); background: var(--main-bg, #f00); font-size: var(--main-font-size); padding: var(--padding-top) 0 10px; } 

This gives you a way to control all of the CSS output from one place (from Sass) and start getting familiar with the syntax. Plus, you can reuse Sass variables and logic with the mixin.

When all of the browsers you want to support work with CSS variables, then all you have to do is add this:

$css-vars-use-native: true; 

Instead of aligning the variable properties in the resulting CSS, the mixin will start registering custom properties, and the var() instances will go to the resulting CSS without any transformations. This means you’ll have fully switched to CSS custom properties and will have all of the advantages we discussed.

If you want to turn on the useful debugging information, add the following:

$css-vars-debug-log: true; 

This will give you:

  • a log when a variable was not assigned but was used;
  • a log when a variable is reassigned;
  • information when a variable is not defined but a default value gets passed that is used instead.

Conclusion Link

Now you know more about CSS custom properties, including their syntax, their advantages, good usage examples and how to interact with them from JavaScript.

You have learned how to detect whether they are supported, how they are different from CSS preprocessor variables, and how to start using native CSS variables until they are supported across browsers.

This is the right time to start using CSS custom properties and to prepare for their native support in browsers.

(rb, vf, al, il)

Footnotes Link

  1. 1 https://www.smashingmagazine.com/2014/03/introduction-to-custom-elements/
  2. 2 https://www.smashingmagazine.com/2016/03/houdini-maybe-the-most-exciting-development-in-css-youve-never-heard-of/
  3. 3 https://www.smashingmagazine.com/2016/02/everything-about-google-accelerated-mobile-pages/
  4. 4 https://www.smashingmagazine.com/2016/05/better-architecture-for-ios-apps-model-view-controller-pattern/
  5. 5 http://www.xanthir.com/blog/b4KT0
  6. 6 https://developer.mozilla.org/en-US/docs/Web/CSS/:root
  7. 7 https://www.smashingmagazine.com/wp-content/uploads/2017/03/closure-large-opt.png
  8. 8 https://www.smashingmagazine.com/wp-content/uploads/2017/03/closure-large-opt.png
  9. 9 https://www.smashingmagazine.com/wp-content/uploads/2017/03/closure-scss-large-opt.png
  10. 10 https://www.smashingmagazine.com/wp-content/uploads/2017/03/closure-scss-large-opt.png
  11. 11 ‘http://codepen.io/malyw/pen/MJmebz/’
  12. 12 ‘http://codepen.io/malyw’
  13. 13 ‘http://codepen.io’
  14. 14 ‘http://codepen.io/malyw/pen/bgWerv/’
  15. 15 ‘http://codepen.io/malyw’
  16. 16 ‘http://codepen.io’
  17. 17 ‘http://codepen.io/malyw/pen/WRjxOy/’
  18. 18 ‘http://codepen.io/malyw’
  19. 19 ‘http://codepen.io’
  20. 20 ‘http://codepen.io/malyw/pen/ggWMvG/’
  21. 21 ‘http://codepen.io/malyw’
  22. 22 ‘http://codepen.io’
  23. 23 ‘http://codepen.io/malyw/pen/PWmzQO/’
  24. 24 ‘http://codepen.io/malyw’
  25. 25 ‘http://codepen.io’
  26. 26 https://developer.mozilla.org/en/docs/Web/CSS/all
  27. 27 https://drafts.csswg.org/css-variables/#defining-variables
  28. 28 https://github.com/w3c/webcomponents/issues/300#issuecomment-144551648
  29. 29 ‘http://codepen.io/malyw/pen/KzZXRq/’
  30. 30 ‘http://codepen.io/malyw’
  31. 31 ‘http://codepen.io’
  32. 32 https://codepen.io/malyw/pen/XpRjNK
  33. 33 https://codepen.io/malyw/pen/EZmgmZ
  34. 34 ‘http://codepen.io/malyw/pen/dNWpRd/’
  35. 35 ‘http://codepen.io/malyw’
  36. 36 ‘http://codepen.io’
  37. 37 https://blog.hospodarets.com/passing_data_from_sass_to_js
  38. 38 https://developer.mozilla.org/en/docs/Web/API/Window/matchMedia
  39. 39 ‘http://codepen.io/malyw/pen/xgdEQp/’
  40. 40 ‘http://codepen.io/malyw’
  41. 41 ‘http://codepen.io’
  42. 42 https://codepen.io/malyw/pen/oBWMOY
  43. 43 http://caniuse.com/#feat=css-variables
  44. 44 https://www.smashingmagazine.com/wp-content/uploads/2017/04/css-variables-large-opt.png
  45. 45 https://www.smashingmagazine.com/wp-content/uploads/2017/04/css-variables-large-opt.png
  46. 46 https://developer.mozilla.org/en/docs/Web/CSS/@supports
  47. 47 https://ashleynolan.co.uk/blog/frontend-tooling-survey-2016-results
  48. 48 https://github.com/postcss/postcss-custom-properties
  49. 49 https://github.com/malyw/css-vars
  50. 50 http://cssnext.io/
  51. 51 https://github.com/malyw/css-vars

↑ Back to topTweet itShare on Facebook

Web Development Reading List #178: On CAA, Pong.js, And Meaningful Work

artificial intelligence 5291510 1920

Web Development Reading List #178: On CAA, Pong.js, And Meaningful Work

Looking at recent discussions, I feel that more and more people are starting to think about ethically and morally correct work. Many of us keep asking themselves if their work is meaningful or if it matters at all. But in a well-functioning society, we need a variety of things to live a good life. The people writing novels that delight us are just as important as those who fight for our civil rights.

It’s important that we have people building services that ease other people’s lives and it’s time to set our sense of urgency right again. Once we start to value other people’s work, the view we have on our own work will start to change, too. As we rely on book authors, for example, other people rely on us to be able to buy the books via a nice, fast and reliable web service.

Further Reading on SmashingMag: Link

News Link

  • Good news if you’re using PostgreSQL: The upcoming PostgreSQL 10 offers some great new features5. It’ll support logical replication in addition to the already existing logical decoding, up to 4x faster parallel query, SCRAM Authentication, and a lot of other useful things.
  • Alexis Deveria creates the amazing project caniuse.com6, a site that we all use a lot. Now he accepts donations, and in return, you can also get an ad-free experience on the site. If you rely on caniuse.com for your work, consider showing your appreciation for the hard work that the author puts into it by giving something back7.
  • With the new Windows 10 Creators Update8, Edge 15 went live. It comes with a new tab management interface, a book reader mode, and better energy efficiency. But even more interesting for us are the implementation of the Web Payment Request API, CSS Custom Property support, Brotli support, WebRTC, async/await, and Intersection Observer.

General Link

  • André Staltz shares his most valuable piece of advice to be a better programmer: “Gain a deeper understanding of the system,” and he has strong points in his article9 that reinforce this.

Security Link

  • There’s a new DNS resource record: CAA. The Certificate Authority Authorization Record10 lets you specify which certificate authority is allowed to issue a certificate for your domain. From September 2017 on, CAs are required to check against these records, so you should consider adding that record to your DNS records as soon as possible.
  • Andrew Reed and Michael Kranch explain how they managed to identify HTTPS-protected Netflix videos in real time11 (PDF, 0.7MB). A technical write-up about HTTPS issues that aren’t easy to fix.

Web Performance Link

13
Sending messages when a user is back online — Phil Nash explains how to do it14. (Image credit15)

HTML & SVG Link

JavaScript Link

Vue.js cheatsheet18
Marcos Neves’ handy cheat sheet19 has everything you need to know about Vue.js at one glance.

Work & Life Link

Going Beyond… Link

  • Linda Besner wrote about living in a globalized yet fragmented world, where sleep is one of the few bodily experiences we seem to share22. A thoughtful piece about what the Internet achieved and where it struggles to connect people.
  • Josh Clark on why the smart algorithm systems that power Google, Siri, Alexa and other “intelligent” AI services should know when they’re not smart enough23 and indicate that to users.
  • Microplastics are everywhere. They’re used in most creams, shower gels and a lot of other products we use every day. Scientists now found microplastics in commercial salts24 from several countries, indicating how badly our seas are polluted with these particles. As we’re eating salt, this has a direct effect on our health, and it’s only stoppable if we achieve to not have microplastic particles in everyday products anymore.

Last but not least, if you’re in Europe or Germany, how about joining the awesome CSSconf EU in Berlin on May, 5th25? There are still tickets available. I’ll be around at the sold-out beyondtellerrand in Düsseldorf again, and I’d love to meet you there. If you don’t have a ticket, maybe join one of the side events26? Or consider the Material Conference27 which will take place on August 17th in Iceland, a lovely island, and I’m sure the event will be great as well.

And with that, I’ll close for this week. If you like what I write each week, please support me with a donation28 or share this resource with other people. You can learn more about the costs of the project here29. It’s available via email, RSS and online.

— Anselm

Footnotes Link

  1. 1 https://www.smashingmagazine.com/2016/02/making-a-service-worker/
  2. 2 https://www.smashingmagazine.com/2016/08/how-to-create-a-responsive-8-bit-drum-machine-using-web-audio-svg-and-multitouch/
  3. 3 https://www.smashingmagazine.com/2016/05/a-guide-to-personal-side-projects/
  4. 4 https://www.smashingmagazine.com/2017/01/algorithm-driven-design-how-artificial-intelligence-changing-design/
  5. 5 https://rhaas.blogspot.de/2017/04/new-features-coming-in-postgresql-10.html
  6. 6 https://caniuse.com/
  7. 7 https://www.patreon.com/caniuse
  8. 8 https://docs.microsoft.com/en-us/microsoft-edge/dev-guide#whats-new-in-edgehtml-15
  9. 9 https://staltz.com/the-single-tip-that-made-me-a-better-programmer.html
  10. 10 https://ma.ttias.be/caa-checking-becomes-mandatory-ssltls-certificates/
  11. 11 http://www.mjkranch.com/docs/CODASPY17_Kranch_Reed_IdentifyingHTTPSNetflix.pdf
  12. 12 https://www.twilio.com/blog/2017/02/send-messages-when-youre-back-online-with-service-workers-and-background-sync.html
  13. 13 https://www.twilio.com/blog/2017/02/send-messages-when-youre-back-online-with-service-workers-and-background-sync.html
  14. 14 https://www.twilio.com/blog/2017/02/send-messages-when-youre-back-online-with-service-workers-and-background-sync.html
  15. 15 https://www.twilio.com/blog/2017/02/send-messages-when-youre-back-online-with-service-workers-and-background-sync.html
  16. 16 https://css-tricks.com/pong-svg-js/
  17. 17 https://vuejs-tips.github.io/cheatsheet/
  18. 18 https://vuejs-tips.github.io/cheatsheet/
  19. 19 https://vuejs-tips.github.io/cheatsheet/
  20. 20 https://colloq.io/blog/remote-managing-a-side-project-across-the-globe
  21. 21 https://blog.bigcartel.com/what-makes-work-meaningful/
  22. 22 http://reallifemag.com/sleep-country/
  23. 23 https://bigmedium.com/ideas/systems-smart-enough-to-know-theyre-not-smart-enough.html
  24. 24 http://www.nature.com/articles/srep46173
  25. 25 http://2017.cssconf.eu/
  26. 26 https://beyondtellerrand.com/events/duesseldorf-2017/side-events
  27. 27 https://web.material.is/2017/
  28. 28 https://wdrl.info/donate
  29. 29 https://wdrl.info/costs/

↑ Back to topTweet itShare on Facebook

Using Slack To Monitor Your App

artificial intelligence 5291510 1920

Using Slack To Monitor Your App

For the past few months, I’ve been building a software-as-a-service (SaaS) application, and throughout the development process I’ve realized what a powerful tool Slack (or team chat in general) can be to monitor user and application behavior. After a bit of integration, it’s provided a real-time view into our application that previously didn’t exist, and it’s been so invaluable that I couldn’t help but write up this show-and-tell.

It all started with a visit to a small startup in Denver, Colorado. During my visit, I started hearing a subtle and enchanting “ding” in the corner of the office every few minutes. When I went to investigate this strange noise, I found a service bell hooked up to a Raspberry Pi, with a tiny metal hammer connected to the circuit board. As it turned out, the Pi was receiving messages from the team’s server, and it swung that little hammer at the bell every time a new customer signed up.

I always thought that was a great team motivator, and it got me thinking of how I could use team chat to achieve a similar experience.

Because we were already using Slack for team chat, and because it has a beautifully documented API1, it was an obvious choice for the experiment.

Further Reading on SmashingMag: Link

Set Up Slack Link

First, we had to obtain a “webhook URL” from Slack in order to programmatically post messages to our Slack channel.

6
Follow the steps above to obtain a webhook URL from Slack (View large version7)

Now that we had a webhook URL, it was time to integrate Slack messages into our Node.js application. To do this, I found a handy Node.js module named node-slack8.

First, we installed the Node.js module:

npm install node-slack --save 

Now, we could send Slack messages to our channel of choice with a few lines of code.

// dependency setup var Slack = require('node-slack'); var hook_url = 'hook_url_goes_here'; var slack = new Slack(hook_url); // send a test Slack message slack.send({ text: ':rocket: Nice job, I'm all set up!', channel: '#test', username: 'MyApp Bot' }); 

(You can find similar Slack integration packages for Ruby9, Python10 and just about any other language.)

When executed, this code produced the following message in our #test Slack channel:

Slack Setup11

The code above is minimal, but it’s specific to the Slack API and the node-slack module. I didn’t want to be locked into any particular messaging service, so I created a generic Node.js module function to execute the service-specific code:

// Messenger.js // dependency setup var hook_url = my_hook_url; var Slack = require('node-slack'); var slack = new Slack(hook_url); module.exports = { sendMessage: function(message, channel, username) { if (!message){ console.log('Error: No message sent. You must define a message.') } else { // set defaults if username or channel is not passed in var channel = (typeof channel !== 'undefined') ? channel : "#general"; var username = (typeof username !== 'undefined') ? username : "MyApp"; // send the Slack message slack.send({ text: message, channel: channel, username: username }); return; } } }; 

Now we can use this module anywhere in the application with two lines of code, and if we ever decide to send messages to another service in the future, we can easily swap that out in Messenger.js.

var messenger = require('./utilities/messenger'); messenger.sendMessage(':rocket: Nice job, I'm all set up!', '#test'); 

Now that we had the basics set up, we were ready to start firing off messages from within the application.

Track Registrations Link

The first order of business was to achieve service-bell parity. I located the success callback of the user registration function, and I added this code:

messenger.sendMessage('New user registration! ' + user.email); 

Now, when someone registered, we’d get this message:

New User Message12

It even dings! This was a good start, and it gave me that satisfying service-bell feeling, but it made me thirsty for more.

Dive Deeper Link

As my curiosity grew with each ding, I began to wonder things like, What if there was a failure to create a new user? What if a user registered, logged in but didn’t complete the onboarding process? What is the result of our scheduled tasks? Now that the groundwork was in place, answering these questions was a piece of cake.

Monitor Exceptions and Critical Errors on Back End Link

One of the most important errors we wanted to know about was if there was a failure to create a new user. All we had to do was find the error callback in the user registration function, and add this code:

messenger.sendMessage(':x: Error While adding a new user ' + formData.email + ' to the DB. Registration aborted!' + error.code + ' ' + error.message); 

Now we knew instantly when registrations failed, why they failed and, more importantly, who they failed for:

User Registration Error13
(View large version14)

There were all kinds of interesting places where we could send messages (pretty much anywhere with an error callback). One of those places was this generic catch-all error function:

app.use(function(err, req, res, next) { var message = ':x: Generic Server Error! '+ err + 'n Request: n' + req.protocol + '://' + req.get('host') + req.originalUrl + 'n' + JSON.stringify(req.headers) + 'Request Payload:n' + JSON.stringify(req.body); messenger.sendMessage(message, '#server-errors'); res.status(err.status || 500); res.json({'error': true }); }); 

This code helped us to uncover what a request looks like for unhanded exceptions. By looking at the request that triggered these errors, we could track down the root causes and fix them until there were no more generic errors.

With all of these error notifications in place, we now had comfort in knowing that if something major failed in the app, we would know about it instantly.

Monitor Financials Link

Next, I wanted to send a notification when a financial event happens in the application. Because our SaaS product integrates with Stripe, we created a webhook endpoint that gets pinged from Stripe when people upgrade their plan, downgrade their plan, add payment info, change payment info and many other events related to subscription payments, all of which are sent to Slack:

Payment Message15

Monitor User Behavior on Front End Link

There were a few cases on the front end where we wanted to understand user behavior in ways that the back end couldn’t provide, so we created an endpoint to send Slack messages directly from the front end. Because our Slack webhook URL is protected behind a POST endpoint, it was a minimal risk to expose sending Slack messages to our team via an endpoint.

With the endpoint in place, we could now fire off Slack messages with a simple AngularJS $http.post call:

// send Slack notification from the front end var message = ":warning: Slack disconnected by " + $scope.user.username; $http.post('/endpoint', message); 

This helps us to answer important questions about the business: Are people registering and adding a domain name? Are they not? If someone is, is it for a really high-profile domain whose owner we would want to reach out to personally soon after they’ve added it. We can now tap into this:

User Messages16
(View large version17)

At one point, we saw a pattern of people adding a domain, removing it, then readding it within a few minutes, which clued us into an obscure bug that we probably would never have discovered otherwise.

There are also signals that a user is unhappy with the service, and these are valuable to know about. Did someone remove a domain name? Did they disconnect Slack?

User Disconnected Messages18
(View large version19)

This feedback gives us an opportunity to proactively reach out and offer delightful customer support when it matters most.

Monitor Scheduled Tasks Link

One of the most interesting things to see in Slack is the result of scheduled tasks. Our SaaS product runs tasks to notify people about their website’s performance (our core service), to send transactional emails, to clean up the database and a few other things. The firing and results of these tasks sends a message to Slack:

Server Task Messages20
(View large version21)

Now we know when a task function fires, what the result of that function is (in this case, it sends out several emails) and whether it fails for any reason.

Apply This Concept To Your Application Link

The case study above is a practical example of what we did to monitor the GoFaster.io22 application and service. It has worked fantastic for us, but how would this concept scale to large applications that send hundreds, maybe even thousands, of messages per day? As you can imagine, this would quickly turn into a “Slackbot who cried wolf” situation, and the value would get lost in the noise.

Don’t Treat All Notifications Equally Link

Some notifications are more important than others, and importance will vary depending on the employee and their role. For example, software development and IT operations (DevOps) folk might only care about the server messages, whereas customer service folk would care most about what’s going on with users.

Luckily, Slack has a great solution to this problem: channels.

Channels can be created by anyone, made public or private to your organization, and shared with anyone. Once you’ve subscribed to a channel, you can control how that channel’s activities alert you. Does a new message in the channel ding every time? Does it alert your phone, too? Does it only bold the channel? All of this can be controlled for each channel by each team member to suit their needs.

Putting this idea into practice, here’s how a larger organization might organize monitor-based notifications in Slack via channels:

#Critical-Server-Errors Link

  • What: registration errors, login errors, database read and write errors
  • Who: system administrators, DevOps, CTO, CEO, developers
  • Alert settings: Always notify on phone or desktop.

#Non-Critical-Server-Errors Link

  • What: 404 errors, catch-all server errors, etc.
  • Who: DevOps, developers
  • Alert settings: Make bold but don’t ding.

#Financials Link

  • What: payment transactions, failed transactions, upgrades, downgrades, expired cards
  • Who: CFO, CEO
  • Alert settings: Make it rain.

#User-Behavior Link

  • What: registering, onboarding process, updating plan type, adding information, removing information, deleting account
  • Who: customer support, social media managers, developers, CEO
  • Alert settings: Always notify on phone or desktop.

#Application-Stats Link

  • What: scheduled task results, housekeeping, transactional email statistics, user count and growth metrics
  • Who: email marketers, system administrators, anyone interested
  • Alert settings: Make bold but don’t ding.

Conclusion Link

Having built on this idea for a few months and digested the results, we’ve found it to be an invaluable extension of our application. Without it, we would feel out of touch with what is going on with the service and would have to manually hunt down the same information via the dashboard, or database queries would be a chore.

Every application and user base is different, which means that this concept cannot be built into a service and offered to the masses. In order to be valuable, it requires a small up-front investment of time and resources to deeply integrate in your application. Once it’s up and running, the investment will pay off in the form of your team’s connectedness to your application and its users.

In conclusion, here’s a recap of the benefits of using team chat to monitor your application:

Gain a Fresh Perspective on User and Server Behavior Link

Having a real-time live feed of the metrics that matter most to you and your business will keep you closely connected to what users are doing and how the server is responding.

React Quickly When Things Fail Link

You will be able to react faster than ever before. You will know about failures at the same time your users do. You can immediately react to that failing endpoint, lost database connection or DDoS attack.

Offer Exceptional Customer Service Link

Reach out to that customer who has just disabled their account to offer them a discount, give personal thanks to customers who have upgraded, or just follow up with people to understand their intentions. When you know what users are doing and when they are doing it, you can easily find out why.

Team Connectedness to the Application Will Make You More Efficient Link

When your team is on the same page with the application, collaboration can center on solving problems as they arise, rather than on trying to figure out what happened, where it happened or who it happened to.

Notifications and Channels Can Scale With Your Application Link

As your application and team grow, so will your monitoring needs. Slack does a great job of giving you all of the permission and notification controls necessary to ensure that the right information gets to the right people.

Search Is Powerful Link

By logging a user name in your Slack messages, you can track every error, success message or event that a user has generated while interacting with your application simply by searching for their user name in Slack. Just know that, with a free Slack account, this is limited to the last 10,000 messages.

Search Slack by User Name23

I hope you’ve found this concept to be useful, and I’d love to hear other stories of teams that have implemented similar forms of monitoring, or just other interesting ways to use and build on it.

(rb, vf, yk, al, il)

Footnotes Link

  1. 1 https://api.slack.com/custom-integrations
  2. 2 https://www.smashingmagazine.com/2016/07/conversational-interfaces-where-are-we-today-where-are-we-heading/
  3. 3 https://www.smashingmagazine.com/2014/05/team-collaboration-closing-efficiency-gaps-responsive-design/
  4. 4 https://www.smashingmagazine.com/2016/11/what-everyone-should-know-about-the-process-behind-app-design/
  5. 5 https://www.smashingmagazine.com/2014/08/getting-started-with-design-sprints/
  6. 6 https://www.smashingmagazine.com/wp-content/uploads/2017/02/slack-setup-large-opt.png
  7. 7 https://www.smashingmagazine.com/wp-content/uploads/2017/02/slack-setup-large-opt.png
  8. 8 https://github.com/xoxco/node-slack
  9. 9 https://github.com/stevenosloan/slack-notifier
  10. 10 https://github.com/slackapi/python-slackclient
  11. 11 https://www.smashingmagazine.com/wp-content/uploads/2017/02/all-setup-preview-opt.png
  12. 12 https://www.smashingmagazine.com/wp-content/uploads/2017/02/new-user-preview-opt.png
  13. 13 https://www.smashingmagazine.com/wp-content/uploads/2017/02/registration-error-large-opt.png
  14. 14 https://www.smashingmagazine.com/wp-content/uploads/2017/02/registration-error-large-opt.png
  15. 15 https://www.smashingmagazine.com/wp-content/uploads/2017/02/payment-preview-opt.png
  16. 16 https://www.smashingmagazine.com/wp-content/uploads/2017/02/user-messages-large-opt.png
  17. 17 https://www.smashingmagazine.com/wp-content/uploads/2017/02/user-messages-large-opt.png
  18. 18 https://www.smashingmagazine.com/wp-content/uploads/2017/02/user-disconnected-large-opt.png
  19. 19 https://www.smashingmagazine.com/wp-content/uploads/2017/02/user-disconnected-large-opt.png
  20. 20 https://www.smashingmagazine.com/wp-content/uploads/2017/02/task-messages-large-opt.png
  21. 21 https://www.smashingmagazine.com/wp-content/uploads/2017/02/task-messages-large-opt.png
  22. 22 https://gofaster.io
  23. 23 https://www.smashingmagazine.com/wp-content/uploads/2017/02/slack-search-preview-opt.png

↑ Back to topTweet itShare on Facebook

AMP For Retailers: Is It Worth It?

artificial intelligence 5291510 1920

AMP For Retailers: Is It Worth It?

Big news from Google: Within a few months, the infamous search engine will divide its index1 to give users better and fresher content. The long-term plan is to make the mobile search index the primary one. Why does this matter for e-commerce website owners?

Well, it will enable Google to run its ranking algorithm differently for purely mobile content. This means that mobile content won’t be extracted from desktop content to determine mobile rankings. That’s definitely something that retailers can leverage, thanks to AMP. This article outlines how to get started with AMP and how to gain an edge over the competition with your e-commerce website.

Further Reading on SmashingMag: Link

AMP For Purely Mobile Content Link

So, how do online retailers go about leveraging this big Google announcement? With AMP content! AMP (Accelerated Mobile Pages) just celebrated its one-year anniversary. It is an open-source project supported by Google that aims to reduce page-loading times on mobile. AMP pages are similar to HTML pages, with a few exceptions: Some tags are different, some rules are new, and there are plenty of restrictions on the use of JavaScript and CSS.

AMP pages get their own special carousel in Google mobile search results. No official statement has been made yet about whether these AMP pages will be getting an SEO boost.

6
AMP pages get their own carousel in Google mobile search results. (Image: Myriam Jessier7) (View large version8)

Is AMP Worth It? Link

While initially geared to blogs and news websites, AMP has introduced components that make it easy to adapt to an e-commerce website. To date, more than 150 million AMP documents are in Google’s index, with over 4 million being added every week. AMP isn’t meant purely for mobile traffic; it renders well on mobile, tablet and desktop. The AMP project’s website9 is actually coded in AMP HTML, in case you are curious to see what AMP looks like on a desktop. eBay was one of the most notable early adopters in the e-commerce realm; by July 2016, it took more than 8 million product pages live in AMP format and plans on going further.

Arguments In Favor Of AMP Link

Conversions, Conversions, Conversions Link

Google is touting a reduction of 15 to 85% in page-loading time on mobile. The main advantage of AMP for retailers is that slow loading times kill conversions. Selling products to people when they want them makes a huge difference to a business’ bottom line. Many shoppers will go to a competitor’s website if yours is too slow to load. Put that in a mobile context, and a slow loading time means losing 40% of visitors — potential customers who will take their dollars elsewhere.

Visibility Is Key Link

In brick and mortar stores, shop fronts are a big deal in attracting customers. It’s the same online, except that your storefront is supported by the speed of your customers’ Internet connection and the visibility you get on various channels (such as search engines, social media and email). Visibility is another way retailers can leverage AMP. Visibility is also a major element of the AMP equation. This is especially true in countries with limited mobile broadband speed10. And before you think this particular challenge is exclusive to developing nations, keep in mind that the US is not ranked in the top 10 countries in mobile broadband speed.

AMP pages feel like they load blazingly fast. Here’s a comparison:


Non-AMP page loading

AMP page loading

Mobile-Friendly Is A Thing Of The Past For Google Link

User experience is central to most online retailers. A slow website with bloated code, an overwrought UI and plenty of popups is everyone’s nightmare, especially on a mobile device.

The “mobile-friendly” label was introduced by Google in late 2014 as an attempt to encourage websites to ensure a good mobile user experience. After widespread adoption of responsive design, the mobile-friendly label is being retired by Google in favor of the AMP label.

How to be a popstar search result in AMP format11
This is how AMP results show up in Google mobile currently. (Image: Myriam Jessier) (View large version12)

AMP pages could be featured in a carousel and are labelled with a dedicated icon, highlighting them in search results. The search giant has recently stated that AMP would take precedence over other mobile-friendly alternatives such as in-app indexing. However, AMP is still not a ranking signal13, according to Google Webmaster Trends analyst John Mueller.

AMP: Because Mobile-Friendly Doesn’t Cut It Anymore Link

Media queries adapt the presentation of content to the device. However, the content of the page itself isn’t affected. In contrast, AMP helps make mobile web pages truly fast to load, but at a cost. Developers, designers and marketers will have to learn how to create beautiful web pages that convert using a subset of HTML with a few extensions.

AMP For E-Commerce Link

The premise of AMP14 is that mobile-optimized content should load instantly anywhere. It’s a very accessible framework for creating fast-loading mobile web pages. However, compatibility with the AMP format is not guaranteed for all types of websites. This is one of the realities of a constantly evolving project such as AMP. The good news is that many of the arguments against AMP for online retailers no longer hold up.

Benefits For E-Commerce Websites Link

AMP pages are now able to handle e-commerce analytics thanks to the amp-analytics variable. With this variable, statistics are available to analyze an AMP page’s performance in terms of traffic, revenue generated, clickthrough rate and bounce rate. According to the AMP project’s public roadmap15, better mobile payments are planned, after the addition of login-based access, slated for the fourth quarter of 2016.

Product and listing pages are supported in AMP, and they show great potential to add real value to the online customer journey. Keep in mind that 40% of users will abandon a website if it takes longer than 3 seconds to load16. Worse yet, 75% of consumers would rather visit a competitor website than deal with a slow-loading page.

Drawbacks Link

Some of the drawbacks that have been noted are mostly due to the fact that AMP for e-commerce is rather new. There are a few concerns about the quality of the user experience offered by AMP e-commerce pages because some e-commerce functionality is not yet available, such as search bars, faceted search filters, login and cart features. However, frequent updates to the AMP format are planned, so this shouldn’t be a deterrent to those looking to implement it.

How eBay implements AMP pages17
How eBay implements AMP pages (Image: iProspect18) (View large version19)

There has been some grumbling about the format among marketers. AMP relies on simplified JavaScript and CSS. As a consequence, tracking and advertising on AMP pages is less sophisticated than on traditional HTML pages. That being said, the main drawback is that implementing AMP pages effectively will take time and effort. The code is proprietary, heavily restricts JavaScript (iframes are not allowed, for example) and even limits CSS (with some properties being outright banned).

How to Develop AMP Pages for an E-Commerce Website Link

To ensure that your website is AMP-compliant20, check the instructions provided in the AMP project’s documentation21. Keep in mind that AMP pages should be responsive22 or mobile-friendly. A best practice would be to test the implementation of AMP pages against your current mobile website using a designated subset of pages. This will give you a sample to determine whether AMP adds value to your business.

You don’t have to make your entire website AMP-compliant. Start upgrading the website progressively: Pick simple static-content pages first, such as product pages, and then move on to other types of content. This way, you can target highly visible pages in SEO results, which will lead to a big payoff for the website without your having to deal with pages that require advanced functionality not yet supported by AMP.

If your website uses a popular CMS, then becoming AMP-compliant could be as easy as installing a plugin.

  • Magento

    The AMP extension by Plum Rocket23 automatically generates AMP versions of your home page, category pages, product pages and blog pages. An interesting feature is that the AMP home page isn’t just “converted”; you can edit it in Magento’s back end.
  • WordPress

    AMP for WP24 is a plugin that lets you create custom AMP designs without having to code. You can customize the logo, header, footer, images and more. It is compatible with WooCommerce and AdSense. The plugin generates AMP versions of your home page, blog articles, WooCommerce shop, products and categories pages.
  • Shopify

    Nothing yet, but it’s under way!

A Step-By-Step Guide To Implementing AMP On Your E-Commerce Website Link

Let’s break down the process according to the customer journey. AMP offers a selection of prebuilt components to help you craft an enjoyable user experience on an e-commerce website (along with some evolving tools to help you collect data in order to improve it). You can implement four major AMP elements along key points in the customer’s purchasing journey, including on the home page, browsing pages, landing pages, product pages and related product widgets:

  • product descriptions,
  • reviews,
  • product shots,
  • navigation.

The entire purchasing flow can’t be 100% AMP-compliant yet, so you’ll have to plan a gateway to a regular non-AMP page for ordering and completing purchases.

1. Browsing (Home and Product Pages) Link

Users will often start their purchasing journey on a website’s home page or a product category page, because these pages are prominent in search engine results. These pages are great candidates for AMP, as eBay has shown25 by making many of its category pages AMP-compliant. Typically, category pages are static and showcase products for sale. The amp-carousel feature26 offers a way to browse other products in a mobile-optimized way. These products can be organized into subcategories that fit the user’s needs. You can view the annotated code to create a product page over on AMP by Example27.

AMP e-commerce home page28
AMP e-commerce home page (Image: AMP by Example)

2. Landing On A Product Page Link

After browsing to a category page, the next step for our user would be to find an interesting product and click on it. In an AMP-compliant flow, this would lead the user to an AMP product page29.

AMP product page30
AMP product page (Image: AMP by Example)

Your AMP product page could include the following:

Here is a preview of what the AMP carousel looks like on mobile:


AMP mobile carousel>

3. Exploring Related Products Link

Showing related products36 benefits the retailer’s bottom line and the user’s experience. The first product that a user browses to isn’t always the one that fits their need. You can show related products in AMP in two ways:

  • Statically publish a list of related products.
  • Generate the list on the fly using amp-list37 to fire a CORS request to a JSON endpoint that supplies the list of related products. These related products can be populated in an amp-mustache4138 template on the client. This approach is personalized because the content is dynamically generated server-side for each request.

4. Personalizing and Understanding Link

Personalization is a big deal in e-commerce because it increases conversions. To dip into personalization in the AMP format, you can leverage the amp-access39 component to display different blocks of content according to the user’s status. To make it all work, you have to follow the same method as we did with the amp-list40 component: Fire a request at a JSON endpoint, and then present the data in an amp-mustache4138 template. Keep in mind that personalization doesn’t have a leg to stand on without reliable data. Google has been actively extending the tracking options available in AMP.

You can track users at an aggregate level using the amp-analytics component6242; AMP supports several analytics vendors.43

Sidenote: In case you see cdn.ampproject.org in your Google Analytics data, this is normal for AMP pages; cdn.ampproject.org is a cache that belongs to Google. No need to worry about this strange newcomer to your Google Analytics data!

AMP now supports some analytics products, such as Adobe’s and Google’s own. The type attribute will quickly configure the respective product within the code. Here’s an example of type being used for Google Analytics:

<amp-analytics type="googlenalytics">

And here are the types for some of the most common analytics vendors:

  • Adobe: adobeanalytics
  • Google Analytics: googleanalytics
  • Segment: segment
  • Webtrekk: webtrekk
  • Yandex Metrica: metrika

Google Tag Manager44 has taken AMP support one step further with AMP containers. You can now create a container for your AMP pages.

Google Tag Manager AMP Container45
Google Tag Manager’s AMP container (Image: Myriam Jessier)

More than 20 tag types are available out of the box, including third-party vendor tags. Alongside a wider selection of tags, Google has provided built-in variables dedicated to AMP tracking, making it easier for marketers and developers to tag their pages.

46
AMP tracking options in Google Tag Manager (Image: Myriam Jessier)

If you are not using Google Tag Manager, you can implement your tag management service in one of two ways:

  • endpoint

    This acts as an additional endpoint for amp-analytics and conducts marketing management in the back end.
  • config

    This manages tags via a dynamically generated JSON config file, unique to each publisher.

The endpoint approach is the same as the standard approach. The config approach consists of creating a unique configuration for amp-analytics that is specific to each publisher and that includes all of the publisher’s compatible analytics packages. A publisher would configure using a syntax like this:

<amp-analytics config="https://your-dream-tag-manager.example.com/user-id.json">

Many online retailers rely on advertising or showing related products throughout their website to boost revenue. The AMP format is bootstrapped to show ads through <amp-ad> and <amp-embed>. The documentation is quite clear47 on how to implement ads, and the good news is that a wide variety of networks are already supported. Although iframes are not allowed in AMP, two embed types support ads with <amp-embed>: Taboola and Zergnet. If you plan on using ads in AMP, follow these principles48 in your development work:

  • Faster is better.

    Ads should be fast.
  • Beauty matters.

    Keep ads beautiful and innovative.
  • Be safe, be secure.

    All creative must use the HTTPS protocol.

5. Supporting Purchases Link

The previous step was a tricky one because it entails maintaining a seamless user experience while the user transitions to a full HTML page. The process should be fast and consistent for the user. An experience that isn’t consistent with the preceding AMP journey could hurt conversions. If your website is a progressive web app, then amp-install-serviceworker49 is an ideal way to bridge both types of pages within the customer journey, because it allows your AMP page to install a service worker on your domain, regardless of where the user is viewing the AMP page. This means that caching content from your progressive web app can be done preemptively to ensure that the transition is smooth for the customer, because all of the content needed is cached in advance. An easy way to experience the entire AMP e-commerce experience is to head on over to eBay50; see how the company handles the transition from AMP to an HTML checkout process.

6. Keep Caching In Mind Link

AMP works within a smart caching model that enables platforms that refer traffic to AMP pages to use caching and prerendering in order to load web pages super-fast. Be aware of this when analyzing traffic and engagement because you might see less traffic to your own origin when AMP pages are originally hosted (this is why we referred to cdn.ampproject.org in Google Analytics data). The balance of traffic will most likely show up through proxied versions of your pages served by AMP caches.

Tools To Validate AMP Pages Link

  • The AMP Validator51
  • In Google Search Console, AMP-related issues are shared under “Search Appearance”:
AMP validation In Google Search Console52
AMP validation In Google Search Console (Image: Myriam Jessier)

A whole host of useful resources are available if you have any questions:

Experimenting With AMP Link

eBay has shared its experience57 in implementing AMP for its own e-commerce platform:

  • Best practices

    AMP encompasses a lot of best practices for building mobile web pages. Incorporate mobile best practices as part of your regular development lifecycle.
  • Less forking in code

    If you follow AMP best practices when building regular pages as well, you can reuse most of the UI components between AMP and non-AMP pages. That means less forking (except for the JavaScript-based components).
  • AMP component list

    There is a growing list of components58, such as sidebar59, carousel60 and lightbox61, that are critical for a compelling e-commerce experience.
  • Internal search

    Adding AMP’s ecosystem to one’s internal search would be a very interesting prospect for many online retailers.

Mind you, there are some complex parts:

  • Infrastructure components

    Things such as global headers and footers and tracking modules have some JavaScript, which is a no-go for AMP. This adds complexity to development but can be worked around.
  • Tracking

    AMP provides user-activity tracking through its amp-analytics component6242. The component can be configured in various ways, but it is still not sufficient for the granular tracking needs of most online retailers.

However, once you get past the internal hurdles, the payoff can be great. Check out the examples provided by eBay for camera drones63 and the Sony PlayStation64. (Use a mobile device, of course, otherwise you will be redirected to the desktop version.)

SEO-Related Questions Link

SEO experts are pushing for AMP adoption because some see it as a mobile-visibility asset to be leveraged. Here are some SEO points to ensure you get the most out of AMP:

  • Host AMP pages on the same domain as other page versions.
  • The Google AMP cache is a proxy-based content delivery network for delivering all valid AMP documents. It fetches AMP HTML pages, caches them and improves page performance automatically.
  • An AMP page is served to the user from the Google AMP cache, and it will have a different URL so that duplicate content issues are avoided. If you have both AMP and non-AMP versions of your pages, use the <link rel="canonical" href="[canonical URL]" /> tag on the AMP page and <link rel="amphtml" href="[AMP URL]" /> on the regular page. For a standalone AMP page (one that doesn’t have a non-AMP version), specify it as the canonical version: <link rel="canonical" href="https://www.example.com/url/to/amp-document.html" />.
  • One of the most common URL structures is to add /amp/ to the path of the URL.

Conclusion Link

An e-commerce website can’t be 100% compliant with AMP, but there are benefits to adopting the format early on. Online retailers looking for an edge against fierce competition might be wise to turn to this format to grab the attention of mobile customers and nudge open their wallets. More and more websites are converting to the AMP format to increase or maintain their mobile traffic. For an online retailer that has a multi-channel or mobile-first strategy to acquire and retain customers, AMP might be a great way to future-proof their online marketing efforts.

Resources Link

(da, vf, al, yk, il)

Footnotes Link

  1. 1 http://searchengineland.com/google-divide-index-giving-mobile-users-better-fresher-content-261037
  2. 2 https://www.smashingmagazine.com/2016/12/progressive-web-amps/
  3. 3 https://www.smashingmagazine.com/2016/02/everything-about-google-accelerated-mobile-pages/
  4. 4 https://www.smashingmagazine.com/2017/02/current-trends-future-prospects-mobile-app-market/
  5. 5 https://www.smashingmagazine.com/2017/01/case-study-app-indexing-google-worth-the-effort/
  6. 6 https://www.smashingmagazine.com/wp-content/uploads/2017/01/amp-mobile-carousel-large-opt.png
  7. 7
  8. 8 https://www.smashingmagazine.com/wp-content/uploads/2017/01/amp-mobile-carousel-large-opt.png
  9. 9 https://www.ampproject.org/
  10. 10 http://www.xconomy.com/boston/2015/01/08/state-of-the-internet-us-connection-speeds-rank-17th-in-world/
  11. 11 https://www.smashingmagazine.com/wp-content/uploads/2017/01/how-to-be-popstar-amp-format-large-opt.png
  12. 12 https://www.smashingmagazine.com/wp-content/uploads/2017/01/how-to-be-popstar-amp-format-large-opt.png
  13. 13 https://www.youtube.com/watch?v=aoL_As2kzRk#t=950
  14. 14 https://www.smashingmagazine.com/2016/02/everything-about-google-accelerated-mobile-pages/
  15. 15 https://www.ampproject.org/roadmap/
  16. 16 https://blog.kissmetrics.com/loading-time/
  17. 17 https://www.smashingmagazine.com/wp-content/uploads/2017/01/amp-page-ebay-large-opt.jpg
  18. 18 https://www.iprospect.com/~/media/Local/US/Our%20blog/Articles/2016/AMP.jpg?la=en
  19. 19 https://www.smashingmagazine.com/wp-content/uploads/2017/01/amp-page-ebay-large-opt.jpg
  20. 20 https://webmasters.googleblog.com/2016/09/8-tips-to-amplify-your-clients.html
  21. 21 https://www.ampproject.org/docs/get_started/create.html
  22. 22 https://www.ampproject.org/docs/guides/responsive_amp.html
  23. 23 https://store.plumrocket.com/magento-extensions/accelerated-mobile-pages-magento-extension.html
  24. 24 https://wordpress.org/plugins/accelerated-mobile-pages/
  25. 25 http://www.ebaytechblog.com/2016/06/30/browse-ebay-with-style-and-speed/
  26. 26 https://ampbyexample.com/components/amp-carousel/
  27. 27 https://ampbyexample.com/samples_templates/product_listing/preview/
  28. 28 https://www.smashingmagazine.com/wp-content/uploads/2017/01/amp-homepage-example.png
  29. 29 https://ampbyexample.com/samples_templates/product/preview/
  30. 30 https://www.smashingmagazine.com/wp-content/uploads/2017/01/amp-product.png
  31. 31 https://ampbyexample.com/components/amp-carousel/
  32. 32 https://ampbyexample.com/components/amp-video/
  33. 33 https://ampbyexample.com/components/amp-accordion/
  34. 34 https://www.ampproject.org/docs/reference/extended/amp-social-share.html
  35. 35 https://www.ampproject.org/docs/reference/extended/amp-sidebar.html
  36. 36 https://ampbyexample.com/samples_templates/product/preview/#related-products
  37. 37 https://ampbyexample.com/components/amp-list/
  38. 38 https://www.ampproject.org/docs/reference/extended/amp-mustache.html
  39. 39 https://ampbyexample.com/components/amp-access/
  40. 40 https://www.ampproject.org/docs/reference/extended/amp-list.html
  41. 41 https://www.ampproject.org/docs/reference/extended/amp-mustache.html
  42. 42 https://www.ampproject.org/docs/reference/extended/amp-analytics.html
  43. 43 https://www.ampproject.org/docs/reference/extended/amp-analytics.html#analytics-vendors
  44. 44 https://analytics.googleblog.com/2016/10/google-tag-manager-giving-mobile.html
  45. 45 https://www.smashingmagazine.com/wp-content/uploads/2017/01/gtm-amp-container.png
  46. 46 https://www.smashingmagazine.com/wp-content/uploads/2017/01/gtm-amp-tracking.png
  47. 47 https://www.ampproject.org/docs/reference/components/amp-ad
  48. 48 https://amphtml.wordpress.com/2016/01/25/amp-what-about-ads/
  49. 49 https://ampbyexample.com/components/amp-install-serviceworker/
  50. 50 http://www.ebaytechblog.com/2016/06/30/browse-ebay-with-style-and-speed/
  51. 51 https://validator.ampproject.org/
  52. 52 https://www.smashingmagazine.com/wp-content/uploads/2017/01/search-console-amp.jpg
  53. 53 https://productforums.google.com/forum/#!forum/webmasters
  54. 54 http://stackoverflow.com/questions/tagged/amp-html
  55. 55 https://github.com/ampproject/amphtml
  56. 56 https://github.com/ampproject/amphtml/blob/master/CONTRIBUTING.md#contributing-code
  57. 57 http://www.ebaytechblog.com/2016/06/30/browse-ebay-with-style-and-speed/
  58. 58 https://www.ampproject.org/docs/reference/extended.html
  59. 59 https://www.ampproject.org/docs/reference/extended/amp-sidebar.html
  60. 60 https://www.ampproject.org/docs/reference/extended/amp-carousel.html
  61. 61 https://www.ampproject.org/docs/reference/extended/amp-lightbox.html
  62. 62 https://www.ampproject.org/docs/reference/extended/amp-analytics.html
  63. 63 https://cdn.ampproject.org/c/m.ebay.com/sch/amp/Camera-Drones/179697/bn_89951/i.html
  64. 64 https://cdn.ampproject.org/c/m.ebay.com/sch/amp/Sony-PlayStation-4-Video-Game-Consoles/139971/bn_339810/i.html
  65. 65 https://www.ampproject.org
  66. 66 https://www.ampproject.org/roadmap/
  67. 67 https://www.smashingmagazine.com/2016/02/everything-about-google-accelerated-mobile-pages/
  68. 68 http://dbushell.com/2015/10/20/accelerated-mobile-pages/
  69. 69 http://www.wompmobile.com/blog/amp-vs-responsive-web-design/
  70. 70 http://www.inmarketingwetrust.com.au/accelerated-mobile-pages-matter/
  71. 71 https://blog.kissmetrics.com/loading-time/
  72. 72 https://webmasters.googleblog.com/2016/09/8-tips-to-amplify-your-clients.html

↑ Back to topTweet itShare on Facebook

How To Prototype IoT Experiences: Building The Hardware (Part 1)

artificial intelligence 5291510 1920

How To Prototype IoT Experiences: Building The Hardware (Part 1)

The world is constantly evolving with frameworks, such as the Internet of Things (IoT) and virtual reality (VR). These and many others are opening opportunities to rethink how we approach prototyping: They introduce avenues to marry the digital software with the tangible aspect of the overall user engagement.

This two-article series will introduce readers of different backgrounds to prototyping IoT experiences with minimum code knowledge, starting with affordable proof of concept platforms, before moving to costly commercial offerings.

  • “Part 1: Building the Hardware” will identify the problem, the criteria for selecting hardware and, finally, how to put the different pieces of equipment together.
  • In “Part 2: Configuring the Software,” we will continue the discussion by writing the code to control the hardware and connect the hardware to the Internet, and we will design custom interfaces to display the collected data.

We will do this by going over a personal experience I had as a user experience designer while learning the basics of an IoT platform named “Adafruit IO”. This will be a nice introductory case study.

The following are some assumptions about you:

  • You can read code and may have even written some on your own (we’re not going to learn coding basics here).
  • You have some understanding of circuitry and electronics. For more on this, see the “Resources” section.
  • You are curious and like to explore and tinker.

Disclaimer:I am not an electronics engineer or a developer. Please always be careful when exploring electricity and hardware. This tutorial is meant to inspire you to do additional research before finding what works for your circumstances!

If this sounds appealing, let’s dive into part 1!

Further Reading on SmashingMag: Link

The Problem Link

Some Quick Definitions Link

IoT talk is sometimes unnecessary complex. To reduce the jargon, I will use some reader-friendly terms, as defined below.

  • board

    You can think of the board as a mini-computer that holds the software in code form (often called firmware) that is responsible for determining how different sensors and the board itself behave in response to inputs from and outputs to their environment. A more technical term is microcontroller unit (MCU).
  • cloud

    There are a ton of definitions and as many philosophical debates regarding this term. For the purpose of this series, let’s define it as any remote servers, plus inbound and outbound connections to and from them.
  • ecosystem

    This is a collection of hardware and software that create a unique overall experience for the end user.
  • rig

    The board, power supply unit and any attached sensors form a cohesive hardware unit.

Needs and Early Explorations Link

On a cold winter day, I read an article on smart homes being the future, which immediately inspired me to turn my home into a smart one. This translated into several commercial product purchases, including devices from the Nest family, which just whet my appetite.

Controlling my air conditioning and furnace and detecting possible carbon monoxide emissions were not enough! I wanted to go further by having monitoring capabilities over my home security. This includes:

  • tracking doors opening and closing,
  • verifying the occurrence of a fire or flood,
  • looking at temperature and humidity,
  • capturing movement in my garage.

Getting to the point of picking Adafruit IO as the solution was not a simple journey. Before deciding on that platform and the HUZZAH ESP8266 board, I tried several other solutions, with varying success:

  • Generic ESP8266 Board5 (hobbyist)

    I gave this a go before even having selected the cloud platform for it. My experience showed me that programming the board requires additional setup, and pushing code to it is often unreliable. For the rigs that I got up and running, I noticed the Wi-Fi connection dropping completely after only a few days.
  • Samsung SmartThings6 (commercial)

    This is a beautifully designed package of sensors and central wireless hub. It is part of an ecosystem that comes with a handy mobile app and support for third-party products7. I spent considerable time trying to get the sensor-to-hub communication to work, but unfortunately, even with the help of the support team, it did not work. I attributed this to my home being a black hole for all things wireless.
  • Particle.io8 (hobbyist and commercial)

    This ecosystem offers dedicated development tools, various IoT-based boards and robust integration with libraries. I gave it a try and was impressed with the performance and flexibility for the end user. I hit roadblocks when integrating Blynk9, a platform for controlling devices via drag-and-drop interfaces. Though I am putting this approach on hold, I look forward to exploring the Particle-Blynk combination again soon.

Criteria Link

My vision was to have multiple sensors that could be viewed and controlled from a computer or mobile device independently at any time. To accomplish this, I needed both a Wi-Fi-enabled hardware board and a software platform that could talk to it and any attached sensors.

I decided to be more strategic in my choices, so I came up with a list of criteria, in order of priority:

  1. low cost

    For scalability, I wanted to keep the rig (i.e. board, sensors and power supply) in the $25 to $30 range — 50% less costly than commercial offerings.
  2. small board

    I wanted a small size for easy mounting and to have enough space to fit multiple sensors in a custom enclosure.
  3. support community

    In case of problems, access to learning resources and a community are key.
  4. wired power

    In tests, a 9-volt battery lasted only a day. Solar was out of the question due to poor sun coverage of the home. Thus, the board had to be able to be wired to an outlet.
  5. low learning curve

    Though I have some development experience and hardware hacking knowledge, I didn’t want this to be an arduous project.

After exploring the three approaches mentioned further above, I ruled out the following additional equipment, based on the five criteria. Keep in mind that I am giving you the high-level details — a whole article could be written on selecting a board!

Board What it is Why I ruled it out
Arduino Yun10 Offers both wired and wireless Internet connectivity, expandable RAM and onboard memory. The board has a Linux-based distribution, making it a powerful networked computer. The price of the controller ($69) and the bulky size proved to be too limiting. Also, I didn’t need something so powerful. I ended up buying one to test out for a garden watering project.
Raspberry Pi 3 Model B11 In addition to offering wired and wireless connectivity, it has HDMI and audio ports, Bluetooth integration and support for use of a custom-sized SD card with different operating systems. While I could load a Linux-based operating system and use the Python language to accomplish anything, that’s not what I needed. I ended up using this platform for other projects. The $40 price tag and the bulky size were also limiting factors.
Raspberry Pi Zero12 This $5 board packs a big punch. The powerful CPU and large RAM made it a strong contender, as did the small size and large number of GPIO pins. Two things nixed this board. It doesn’t have on-board Wi-Fi, and so requires additional equipment. And because it is very popular, finding this board is hard. In the US, it is sold only at Micro Center13, which limits it to one per home per month. (Note: At the time of writing v1.3 of the board with on board Wi-Fi and Bluetooth was not yet available.)

Side note: For more information on choosing a board for your hardware prototyping project, you can consult the excellent “Makers’ Guide to Boards14.”

Further researching led me to Adafruit’s HUZZAH ESP826615 board, which is but one variation of the ESP8266 chipset; there are others, such as the NodeMCU LUA16. Each has unique capabilities, so choose wisely. Here is why I selected the HUZZAH:

  • the price ($10, not counting shipping);
  • 12+ digital input and output pins and 1 analog pin;
  • an on-board reset button
  • voltage shifting from 3.3 and 5 volts (but it’s primarily a 3.3-volt board)
  • a dedicated IoT service (Adafruit IO) with UI building blocks.

Getting Started Link

Deciding to start small, I wanted to build a sensor that tracks whether a door is open. The rest of this first article will focus on the hardware for this use case, but much of the wiring will scale to other types of sensors.

Tools Link

A good toolkit comes in handy. (View large version17)
  • FTDI cable18 ($8 – $20 on average)

    It’s best to get one that supports 3.3 and 5 volts, in case you want to explore rigs using the original ESP8266 ESP-01 board in the future. It must offer TX and RX LEDs for easier troubleshooting while pushing code to the board. This is used to push the code from the programming computer to the board.
  • Putty19 ($5 – $7 on average)

    This is used to mount the rig without damaging the wall. Various LEGO pieces can be used to keep the sensor in place without moving.
  • Ordinary soldering iron20 ($20 on average)

    This helps to attach the headers (pin legs) to the board.

The following I am assuming you having just laying around: a computer, a solder wire and a solder iron cleaner.

Hardware Components Link

Total: $30 to $40 on average (using US parts)

Connecting The Hardware Link

Before getting to the details of how to put the rig together, let’s talk about what the goal is. By the end of this first article, you should have something similar to what you see below. With this setup, you will have a mini-computer (the board) capable of collecting sensor data from your environment and communicating it to the cloud (Adafruit IO) over Wi-Fi.

Hardware
You can attach multiple sensors, but be aware of the power draw (i.e. how many milliamps each sensor uses) and the length of wire needed to connect them. (View large version3229)

Putting the Board Together Link

The first step is to assemble the HUZZAH board by soldering on its pin headers, including both the board leg headers and the FTDI header. Adafruit has a step-by-step tutorial30 on this.

When you are soldering the first leg header, ensure that the board is not tilting one way, which would result in the pins being soldered at an angle. A trick I used is to put a bit of putty under the board to even it out as it is being plugged into the breadboard.

Once you have soldered all of the headers, insert the board in the breadboard with the antenna (the wavy gold line) facing outwards.

Adding the Breadboard Power Supply Link

Insert the supply at the opposite end of the breadboard, with the top and bottom legs fitting in the + and – breadboard rails. This is how power will be passed to the breadboard.

Next, set the yellow jumpers for both rails to 3.3 volts, which is the voltage used by the HUZZAH board.

Note: Depending on your breadboard, the – and + might not match the alignment of the power supply jumpers. That’s fine as long as you remember that the power supply dictates which breadboard rail carries which electrical signal!

Wiring for Power and Connecting the Sensor Link

Connect the HUZZAH board to the power:

  1. Connect the 3V to the + rail (the power).
  2. Connect the GND to the rail (the ground).

Connecting the sensor is very easy:

  1. Connect the + to the + rail on the breadboard (the power).
  2. Connect the to the rail on the breadboard (the ground).
  3. Connect the S to the #5 on the board (digital input pin).
Hardware
A 9-volt battery is used here to illustrate a power source, but most such batteries might not have adequate power for your rig because they typically carry 400 to 600 milliamps. (View large version31)
Finished Rig
The power adapter is plugged in here but not powered on. Use different colored wires to distinguish between connections. (View large version3229)
Fritzing Diagram
Notice how each pin of the sensor is labeled. (View large version33)

If you are curious to learn how reed switches operate, Chris Woodford has more information34 on the subject.

As a last step, plug the 9-volt adapter into a power outlet, then into the breadboard power supply. Push the white button. If everything is correctly wired, you should see several lights flicker on, including for the power supply (the green one), the board power (red), the Wi-Fi (blue) and the sensor (red if the magnet is touching the sensor).

Mounting the Rig Link

At this point, you can start writing the code for the rig, but I find this is a good opportunity to test the mounting of the container box. This is not a permanent mounting, but a trial run to gauge the rig’s overall dimensions and the best fit. Before doing that, you need to take some steps first.

Step 1: Using your soldering iron, melt one hole in the left side of the container for the power adapter plug, and three smaller ones on the right for the individual sensor wires.

Warning: Make sure to do this in a well-ventilated area, so that you don’t breathe in fumes. After that, clean your soldering iron’s tip with a nonabrasive sponge.

Box hole for power
A similar box can be bought on the cheap in any large store. (View large version35)
Box holes for sensor
Carefully size the holes based on your wires’ thickness. (View large version36)

Step 2: Put the entire rig in the container, and pass the cables through the holes.

Entire rig boxed
While this looks well insulated, it is not suited for outdoor use! (View large version37)

Step 3: Close the container, and mount it on the wall with the putty. Tapes of various types won’t work well. Alternatively, you could punch holes in the bottom of the container to mount with screws, but make sure they are insulated with electrical tape to avoid short-circuiting any electronics.

I have also tried using hot glue. I think it is messy, but it is not all that more expensive, and you can pick one up on the cheap38 if you prefer that method.

Adding mounting putty
Put putty only on the bottom of the container and the sensor. (View large version39)
Rig mounted on wall
You can stack multiple magnets on the door to match the proper distance from the sensor. Make sure it does not touch the glass tube. (View large version40)

Step 4: Use a combination of LEGO pieces and putty to mount the sensor and the accompanying magnet to the door.

Fixing sensor to rig
For a firmer fix, you can put a LEGO piece on top of the two blue blocks. (View large version41)

Now that the rig is all wired up, you can connect to it with the FTDI cable and start adding the code that will make the sensor work.

Lessons Learned And Troubleshooting Link

Equipment Link

  • Using a 5-volt 1-amp power adapter (rather than 9 volts and 1 amp) won’t cut it. In my tests, the rig never powered on this way. I attribute this to the voltage conversion in the breadboard’s power supply.
  • In trying different hall sensors, I was getting readings all over the board. See if they work for you, but my preference remains a reed switch because of its large surface area for interacting with the magnet.

Mounting Link

  • Most 9-volt 1-amp power supplies have short cables. An extension cord is recommended!
  • If you don’t want to damage the mounting surface, putty is your best bet. Given the weight of the rig, tape and other materials won’t work as well.
  • Be careful not to place the reed switch too close to the magnet, or you’ll risk breaking the glass tube when opening and closing the door.

Conclusion Link

In this first article of our two-part series, we’ve identified the problem (home security), assessed the merit of an IoT setup, and discussed the rationale involved in selecting a particular board. This was followed by a step-by-step guide on how to put together all of the hardware components into a working rig.

In doing so, we’ve learned the basics of electronics. In the second and final article in this series, we will add code to the rig we’ve built here, so that we can start interacting with the environment. Then, we will build custom user interfaces to view the data from anywhere, while discussing at a high level the security implications of the software configuration.

Stay tuned!

Resources Link

Basics of Electronics Link

Other Hardware Platforms Link

Parts and Tools Link

(da, vf, al, il)

Footnotes Link

  1. 1 https://www.smashingmagazine.com/2016/09/choosing-the-right-prototyping-tool/
  2. 2 https://www.smashingmagazine.com/2017/03/prototype-code-custom-pull-to-refresh-gesture-animation/
  3. 3 https://www.smashingmagazine.com/2015/01/prototyping-ios-android-apps-sketch-freebie/
  4. 4 https://www.smashingmagazine.com/2013/01/ios-prototyping-with-tap-and-adobe-fireworks-part-1/
  5. 5 http://www.esp8266.com/
  6. 6 https://www.smartthings.com
  7. 7 https://www.smartthings.com/works-with-smartthings
  8. 8 https://www.particle.io/
  9. 9 http://www.blynk.io/
  10. 10 https://www.arduino.cc/en/Main/ArduinoBoardYun
  11. 11 https://www.raspberrypi.org/products/raspberry-pi-3-model-b/
  12. 12 https://www.raspberrypi.org/products/pi-zero/
  13. 13 http://www.microcenter.com/product/457746/Zero_Development_Board
  14. 14 http://makezine.com/comparison/boards/
  15. 15 https://learn.adafruit.com/adafruit-huzzah-esp8266-breakout/overview
  16. 16 https://www.amazon.com/HiLetgo-Version-NodeMCU-Internet-Development/dp/B010O1G1ES
  17. 17 https://www.smashingmagazine.com/wp-content/uploads/2017/02/sm004-01-large-opt.jpg
  18. 18 https://www.adafruit.com/product/70
  19. 19 https://www.amazon.com/Duck-Removable-Mounting-Poster-1436912/dp/B000BQMFEC/
  20. 20 https://www.amazon.com/Tabiger-Soldering-110V-Adjustable-Temperature-Welding/dp/B01H1IFT54/
  21. 21 https://www.adafruit.com/product/2471
  22. 22 https://www.amazon.com/Aketek-Solderless-BreadBoard-tie-points-power/dp/B01258UZMC/
  23. 23 https://www.amazon.com/Phantom-YoYo-Adapter-Power-2-1mm/dp/B009SNK4AQ/
  24. 24 https://www.amazon.com/kwmobile-MB102-Power-Supply-Module/dp/B01JOBT87G/
  25. 25 http://www.gearbest.com/other-accessories/pp_354742.html
  26. 26 https://www.amazon.com/Honbay®-120pcs-Multicolored-Female-Breadboard/dp/B017NEGTXC/
  27. 27 https://www.amazon.com/Cutequeen-Ceramic-Industrial-Ferrite-Magnets/dp/B01HF3BJPY/
  28. 28 https://www.amazon.com/ADVANTUS-Stacker-Crayon-Inches-40311/dp/B00B4NPO08/
  29. 29 https://www.smashingmagazine.com/wp-content/uploads/2017/02/sm004-03-large-opt.jpg
  30. 30 https://learn.adafruit.com/adafruit-huzzah-esp8266-breakout/assembly
  31. 31 https://www.smashingmagazine.com/wp-content/uploads/2017/02/sm004-04-large-opt.jpg
  32. 32 https://www.smashingmagazine.com/wp-content/uploads/2017/02/sm004-03-large-opt.jpg
  33. 33 https://www.smashingmagazine.com/wp-content/uploads/2017/02/sm004-05-large-opt.jpg
  34. 34 http://www.explainthatstuff.com/howreedswitcheswork.html
  35. 35 https://www.smashingmagazine.com/wp-content/uploads/2017/02/sm004-06-large-opt.jpg
  36. 36 https://www.smashingmagazine.com/wp-content/uploads/2017/02/sm004-07-large-opt.jpg
  37. 37 https://www.smashingmagazine.com/wp-content/uploads/2017/02/sm004-08-large-opt.jpg
  38. 38 https://www.amazon.com/CCbetter-Temperature-Melting-Flexible-Projects/dp/B01178RVI2/
  39. 39 https://www.smashingmagazine.com/wp-content/uploads/2017/02/sm004-09-large-opt.jpg
  40. 40 https://www.smashingmagazine.com/wp-content/uploads/2017/02/sm004-10-large-opt.jpg
  41. 41 https://www.smashingmagazine.com/wp-content/uploads/2017/02/sm004-11-large-opt.jpg
  42. 42 https://www.youtube.com/playlist?list=PLjF7R1fz_OOU08_hRcayfVZSmTpBCGJbL
  43. 43 http://makezine.com/
  44. 44 http://makezine.com/2009/12/10/electronics-just-got-a-lot-easier/
  45. 45 https://www.particle.io/products/hardware/photon-wifi-dev-kit
  46. 46 https://www.raspberrypi.org/
  47. 47 https://www.adafruit.com/
  48. 48 https://www.sparkfun.com/
  49. 49 https://www.aliexpress.com/
  50. 50 http://www.gearbest.com

↑ Back to topTweet itShare on Facebook

A Comprehensive Guide To HTTP/2 Server Push

artificial intelligence 5291510 1920

A Comprehensive Guide To HTTP/2 Server Push

The landscape for the performance-minded developer has changed significantly in the last year or so, with the emergence of HTTP/2 being perhaps the most significant of all. No longer is HTTP/2 a feature we pine for. It has arrived, and with it comes server push!

Aside from solving common HTTP/1 performance problems (e.g., head of line blocking and uncompressed headers), HTTP/2 also gives us server push! Server push allows you to send site assets to the user before they’ve even asked for them. It’s an elegant way to achieve the performance benefits of HTTP/1 optimization practices such as inlining, but without the drawbacks that come with that practice.

In this article, you’ll learn all about server push, from how it works to the problems it solves. You’ll also learn how to use it, how to tell if it’s working, and its impact on performance. Let’s begin!

What Is Server Push, Exactly? Link

Accessing websites has always followed a request and response pattern. The user sends a request to a remote server, and with some delay, the server responds with the requested content.

The initial request to a web server is commonly for an HTML document. In this scenario, the server replies with the requested HTML resource. The HTML is then parsed by the browser, where references to other assets are discovered, such as style sheets, scripts and images. Upon their discovery, the browser makes separate requests for those assets, which are then responded to in kind.

1
Typical web server communication (Large preview2)

The problem with this mechanism is that it forces the user to wait for the browser to discover and retrieve critical assets until after an HTML document has been downloaded. This delays rendering and increases load times.

With server push, we have a solution to this problem. Server push lets the server preemptively “push” website assets to the client without the user having explicitly asked for them. When used with care, we can send what we know the user is going to need for the page they’re requesting.

Let’s say you have a website where all pages rely on styles defined in an external style sheet named styles.css. When the user requests index.html from the server, we can push styles.css to the user just after we begin sending the response for index.html.

Web Server Communication with HTTP/2 server push.3
Web server communication with HTTP/2 server push. (Large preview4)

Rather than waiting for the server to send index.html and then waiting for the browser to request and receive styles.css, the user only has to wait for the server to respond with bothindex.html and styles.css on the initial request. This means that the browser can begin rendering the page faster than if it had to wait.

As you can imagine, this can decrease the rendering time of a page. It also solves some other problems, particularly in front-end development workflows.

What Problems Does Server Push Solve? Link

While reducing round trips to the server for critical content is one of the problems that server push solves, it’s not the only one. Server push acts as a suitable alternative for a number of HTTP/1-specific optimization anti-patterns, such as inlining CSS and JavaScript directly into HTML, as well as using the data URI scheme5 to embed binary data into CSS and HTML.

These techniques found purchase in HTTP/1 optimization workflows because they decrease what we call the “perceived rendering time” of a page, meaning that while the overall loading time of a page might not be reduced, the page will appear to load faster for the user. It makes sense, after all. If you inline CSS into an HTML document within <style> tags, the browser can begin applying styles immediately to the HTML without waiting to fetch them from an external source. This concept holds true with inlining scripts and inlining binary data with the data URI scheme.

Web Server Communication with Inlined Content.

Web server communication with inlined content (Large preview6)

Seems like a good way to tackle the problem, right? Sure — for HTTP/1 workflows, where you have no other choice. The poison pill we swallow when we do this, however, is that the inlined content can’t be efficiently cached. When an asset like a style sheet or JavaScript file remains external and modular, it can be cached much more efficiently. When the user navigates to a subsequent page that requires that asset, it can be pulled from the cache, eliminating the need for additional requests to the server.

Optimal caching behavior.7
Optimal caching behavior. (Large preview8)

When we inline content, however, that content doesn’t have its own caching context. Its caching context is the same as the resource it’s inlined into. Take an HTML document with inlined CSS, for instance. If the caching policy of the HTML document is to always grab a fresh copy of the markup from the server, then the inlined CSS will never be cached on its own. Sure, the document that it’s a part of may be cached, but subsequent pages containing this duplicated CSS will be downloaded repeatedly. Even if the caching policy is more lax, HTML documents typically have limited shelf life. This is a trade-off that we’re willing to make in HTTP/1 optimization workflows, though. It does work, and it’s quite effective for first-time visitors. First impressions are often the most important.

These are the problems that server push addresses. When you push assets, you get the practical benefits that come with inlining, but you also get to keep your assets in external files that retain their own caching policy. There is a caveat to this point, though, and it’s covered toward the end of this article. For now, let’s continue.

I’ve talked enough about why you should consider using server push, as well as the problems that it fixes for both the user and the developer. Now let’s talk about how it’s used.

How To Use Server Push Link

Using server push usually involves using the Link HTTP header, which takes on this format:

Link: </css/styles.css>; rel=preload; as=style 

Note that I said usually. What you see above is actually the preload resource hint9 in action. This is a separate and distinct optimization from server push, but most (not all) HTTP/2 implementations will push an asset specified in a Link header containing a preload resource hint. If either the server or the client opts out of accepting the pushed resource, the client can still initiate an early fetch for the resource indicated.

The as=style portion of the header is not optional. It informs the browser of the pushed asset’s content type. In this case, we use a value of style to indicate that the pushed asset is a style sheet. You can specify other content types10. It’s important to note that omitting the as value can result in the browser downloading the pushed resource twice. So don’t forget it!

Now that you know how a push event is triggered, how do we set the Link header? You can do so through two routes:

  • your web server configuration (for example, Apache httpd.conf or .htaccess);
  • a back-end language function (for example, PHP’s header function).

Setting the Link Header in Your Server Configuration Link

Here’s an example of configuring Apache (via httpd.conf or .htaccess) to push a style sheet whenever an HTML file is requested:

<FilesMatch ".html$"> Header set Link "</css/styles.css>; rel=preload; as=style" <FilesMatch> 

Here, we use the FilesMatch directive to match requests for files ending in .html. When a request comes along that matches this criteria, we add a Link header to the response that tells the server to push the resource at /css/styles.css.

Side note: Apache’s HTTP/2 module can also initiate a push of resources using the H2PushResource directive. The documentation for this directive states that this method can initiate pushes earlier than if the Link header method is used. Depending on your specific setup, you may not have access to this feature. The performance tests shown later in this article use the Link header method.

As of now, Nginx doesn’t support HTTP/2 server push, and nothing so far in the software’s changelog11 has indicated that support for it has been added. This may change as Nginx’s HTTP/2 implementation matures.

Setting the Link Header in Back-End Code Link

Another way to set a Link header is through a server-side language. This is useful when you aren’t able to change or override the web server’s configuration. Here’s an example of how to use PHP’s header function to set the Link header:

header("Link: </css/styles.css>; rel=preload; as=style");

If your application resides in a shared hosting environment where modifying the server’s configuration isn’t an option, then this method might be all you’ve got to go on. You should be able to set this header in any server-side language. Just be sure to do so before you begin sending the response body, to avoid potential runtime errors.

Pushing Multiple Assets Link

All of our examples so far only illustrate how to push one asset. What if you want to push more than one? Doing that would make sense, right? After all, the web is made up of more than just style sheets. Here’s how to push multiple assets:

Link: </css/styles.css>; rel=preload; as=style, </js/scripts.js>; rel=preload; as=script, </img/logo.png>; rel=preload; as=image 

When you want to push multiple resources, just separate each push directive with a comma. Because resource hints are added via the Link tag, this syntax is how you can mix in other resource hints with your push directives. Here’s an example of mixing a push directive with a preconnect resource hint:

Link: </css/styles.css>; rel=preload; as=style, <https://fonts.gstatic.com>; rel=preconnect 

Multiple Link headers are also valid. Here’s how you can configure Apache to set multiple Link headers for requests to HTML documents:

<FilesMatch ".html$"> Header add Link "</css/styles.css>; rel=preload; as=style" Header add Link "</js/scripts.js>; rel=preload; as=script" <FilesMatch> 

This syntax is more convenient than stringing together a bunch of comma-separated values, and it works just the same. The only downside is that it’s not quite as compact, but the convenience is worth the few extra bytes sent over the wire.

Now that you know how to push assets, let’s see how to tell whether it’s working.

How To Tell Whether Server Push Is Working Link

So, you’ve added the Link header to tell the server to push some stuff. The question that remains is, how do you know if it’s even working?

This varies by browser. Recent versions of Chrome will reveal a pushed asset in the initiator column of the network utility in the developer tools.

12
Chrome indicating that an asset has been pushed by the server (Large preview13)

Furthermore, if we hover over the asset in the network request waterfall, we’ll get detailed timing information on the asset’s push:

Chrome showing detailed timing information of the pushed asset14
Chrome showing detailed timing information of the pushed asset (Large preview15)

Firefox is less obvious in identifying pushed assets. If an asset has been pushed, its status in the browser’s network utility in the developer tools will show up with a gray dot.

16
Firefox indicating that an asset has been pushed by the server (Large preview17)

If you’re looking for a definitive way to tell whether an asset has been pushed by the server, you can use the nghttp command-line client18 to examine a response from an HTTP/2 server, like so:

nghttp -ans https://jeremywagner.me

This command will show a summary of the assets involved in the transaction. Pushed assets will have an asterisk next to them in the program output, like so:

id responseEnd requestStart process code size request path 13 +50.28ms +1.07ms 49.21ms 200 3K / 2 +50.47ms * +42.10ms 8.37ms 200 2K /css/global.css 4 +50.56ms * +42.15ms 8.41ms 200 157 /css/fonts-loaded.css 6 +50.59ms * +42.16ms 8.43ms 200 279 /js/ga.js 8 +50.62ms * +42.17ms 8.44ms 200 243 /js/load-fonts.js 10 +74.29ms * +42.18ms 32.11ms 200 5K /img/global/jeremy.png 17 +87.17ms +50.65ms 36.51ms 200 668 /js/lazyload.js 15 +87.21ms +50.65ms 36.56ms 200 2K /img/global/book-1x.png 19 +87.23ms +50.65ms 36.58ms 200 138 /js/debounce.js 21 +87.25ms +50.65ms 36.60ms 200 240 /js/nav.js 23 +87.27ms +50.65ms 36.62ms 200 302 /js/attach-nav.js 

Here, I’ve used nghttp on my own website19, which (at least at the time of writing) pushes five assets. The pushed assets are marked with an asterisk on the left side of the requestStart column.

Now that we can identify when assets are pushed, let’s see how server push actually affects the performance of a real website.

Measuring Server Push Performance Link

Measuring the effect of any performance enhancement requires a good testing tool. Sitespeed.io20 is an excellent tool available via npm21; it automates page testing and gathers valuable performance metrics. With the appropriate tool chosen, let’s quickly go over the testing methodology.

Testing Methodology Link

I wanted measure the impact of server push on website performance in a meaningful way. In order for the results to be meaningful, I needed to establish points of comparison across six separate scenarios. These scenarios are split across two facets: whether HTTP/2 or HTTP/1 is used. On HTTP/2 servers, we want to measure the effect of server push on a number of metrics. On HTTP/1 servers, we want to see how asset inlining affects performance in the same metrics, because inlining is supposed to be roughly analogous to the benefits that server push provides. Specifically, these scenarios are the following:

  • HTTP/2 without server push

    In this state, the website runs on the HTTP/2 protocol, but nothing whatsoever is pushed. The website runs “stock,” so to speak.
  • HTTP/2 pushing only CSS

    Server push is used, but only for the website’s CSS. The CSS for the website is quite small, weighing in at a little over 2 KB with Brotli compression22 applied.
  • Pushing the kitchen sink

    All assets in use on all pages across the website are pushed. This includes the CSS, as well as 1.4 KB of JavaScript spread across six assets, and 5.9 KB of SVG images spread across five assets. All quoted file sizes are, again, after Brotli compression has been applied.
  • HTTP/1 with no assets inlined

    The website runs on HTTP/1, and no assets are inlined to reduce the number of requests or increase rendering speed.
  • Inlining only CSS

    Only the website’s CSS is inlined.
  • Inlining the kitchen sink

    All assets in use on all pages across the website are inlined. CSS and scripts are inlined, but SVG images are base64-encoded and embedded directly into the markup. It should be noted that base64-encoded data is roughly 1.37 times larger23 than its unencoded equivalent.

In each scenario, I initiated testing with the following command:

sitespeed.io -d 1 -m 1 -n 25 -c cable -b chrome -v https://jeremywagner.me

If you want to know the ins and outs of what this command does, you can check out the documentation24. The short of it is that this command tests my website’s home page at https://jeremywagner.me25 with the following conditions:

  • The links in the page are not crawled. Only the specified page is tested.
  • The page is tested 25 times.
  • A “cable-like” network throttling profile is used. This translates to a round trip time of 28 milliseconds, a downstream speed of 5,000 kilobits per second and an upstream speed of 1,000 kilobits per second.
  • The test is run using Google Chrome.

Three metrics were collected and graphed from each test:

  • first paint time

    This is the point in time at which the page can first be seen in the browser. When we strive to make a page “feel” as though it is loading quickly, this is the metric we want to reduce as much as possible.
  • DOMContentLoaded time

    This is the time at which the HTML document has completely loaded and has been parsed. Synchronous JavaScript code will block the parser and cause this figure to increase. Using the async attribute on <script> tags can help to prevent parser blocking.
  • page-loading time

    This is the time it takes for the page and its assets to fully load.

With the parameters of the test determined, let’s see the results!

Test Outcomes Link

Tests were run across the six scenarios specified earlier, with the results graphed. Let’s start by looking at how first paint time is affected in each scenario:

First paint time26
First paint time (Large preview27)

Let’s first talk a bit about how the graph is set up. The portion of the graph in blue represents the average first paint time. The orange portion is the 90th percentile. The grey portion represents the maximum first paint time.

Now let’s talk about what we see. The slowest scenarios are both the HTTP/2- and HTTP/1-driven websites with no enhancements at all. We do see that using server push for CSS helps to render the page about 8% faster on average than if server push is not used at all, and even about 5% faster than inlining CSS on an HTTP/1 server.

When we push all assets that we possibly can, however, the picture changes somewhat. First paint times increase slightly. In HTTP/1 workflows where we inline everything we possibly can, we achieve performance similar to when we push assets, albeit slightly less so.

The verdict here is clear: With server push, we can achieve results that are slightly better than what we can achieve on HTTP/1 with inlining. When we push or inline many assets, however, we observe diminishing returns.

It’s worth noting that either using server push or inlining is better than no enhancement at all for first-time visitors. It’s also worth noting that these tests and experiments are being run on a website with small assets, so this test case may not reflect what’s achievable for your website.

Let’s examine the performance impacts of each scenario on DOMContentLoaded time:

DOMContentLoaded time28
DOMContentLoaded time (Large preview29)

The trends here aren’t much different than what we saw in the previous graph, except for one notable departure: The instance in which we inline as many assets as practical on a HTTP/1 connection yields a very low DOMContentLoaded time. This is presumably because inlining reduces the number of assets needed to be downloaded, which allows the parser to go about its business without interruption.

Now, let’s look at how page-loading times are affected in each scenario:

Page-loading time30
Page-loading time (Large preview31)

The established trends from earlier measurements generally persist here as well. I found that pushing only the CSS realized the greatest benefit to loading time. Pushing too many assets could, on some occasions, make the web server a bit sluggish, but it was still better than not pushing anything at all. Compared to inlining, server push yielded better overall loading times than inlining did.

Before we conclude this article, let’s talk about a few caveats you should be aware of when it comes to server push.

Caveats On Using Server Push Link

Server push isn’t a panacea for your website’s performance maladies. It has a few drawbacks that you need to be cognizant of.

You Can Push Too Much Stuff Link

In one of the scenarios above, I am pushing a lot of assets, but all of them altogether represent a small portion of the overall data. Pushing a lot of very large assets at once could actually delay your page from painting or being interactive sooner, because the browser needs to download not only the HTML, but all of the other assets that are being pushed alongside of it. Your best bet is to be selective in what you push. Style sheets are a good place to start (so long as they aren’t massive). Then evaluate what else makes sense to push.

You Can Push Something That’s Not on the Page Link

This is not necessarily a bad thing if you have visitor analytics to back up this strategy. A good example of this may be a multi-page registration form, where you push assets for the next page in the sign-up process. Let’s be crystal clear, though: If you don’t know whether you should force the user to preemptively load assets for a page they haven’t seen yet, then don’t do it. Some users might be on restricted data plans, and you could be costing them real money.

Configure Your HTTP/2 Server Properly Link

Some servers give you a lot of server push-related configuration options. Apache’s mod_http2 has some options for configuring how assets are pushed. The H2PushPriority setting32 should be of particular interest, although in the case of my server, I left it at the default setting. Some experimentation could yield additional performance benefits. Every web server has a whole different set of switches and dials for you to experiment with, so read the manual for yours and find out what’s available!

Pushes May Not Be Cached Link

There has been some gnashing of teeth over whether server push could hurt performance in that returning visitors may have assets needlessly pushed to them again. Some servers do their best to mitigate this. Apache’s mod_http2 uses the H2PushDiarySize setting33 to optimize this somewhat. H2O Server has a feature called Cache Aware server push34 that uses a cookie mechanism to remember pushed assets.

If you don’t use H2O Server, you can achieve the same thing on your web server or in server-side code by only pushing assets in the absence of a cookie. If you’re interested in learning how to do this, then check out a post I wrote about it on CSS-Tricks35. It’s also worth mentioning that browsers can send an RST_STREAM frame to signal to a server that a pushed asset is not needed. As time goes on, this scenario will be handled much more gracefully.

As sad it may seem, we’re nearing the end of our time together. Let’s wrap things up and talk a bit about what we’ve learned.

Final Thoughts Link

If you’ve already migrated your website to HTTP/2, you have little reason not to use server push. If you have a highly complex website with many assets, start small. A good rule of thumb is to consider pushing anything that you were once comfortable inlining. A good starting point is to push your site’s CSS. If you’re feeling more adventurous after that, then consider pushing other stuff. Always test changes to see how they affect performance. You’ll likely realize some benefit from this feature if you tinker with it enough.

If you’re not using a cache-aware server push mechanism like H2O Server’s, consider tracking your users with a cookie and only pushing assets to them in the absence of that cookie. This will minimize unnecessary pushes to known users, while improving performance for unknown users. This not only is good for performance, but also shows respect to your users with restricted data plans.

All that’s left for you now is to try out server push for yourself. So get out there and see what this feature can do for you and your users! If you want to know more about server push, check out the following resources:

Thanks to Yoav Weiss39 for clarifying that the as attribute is required (and not optional as the original article stated), as well as a couple of other minor technical issues. Additional thanks goes to Jake Archibald40 for pointing out that the preload resource hint is an optimization distinct from server push.

This article is about an HTTP/2 feature named server push. This and many other topics are covered in Jeremy’s book Web Performance in Action41. You can get it or any other Manning Publications42 book for 42% off with the coupon code sswagner!

(rb, vf, al, il)

Footnotes Link

  1. 1 http://provide.smashingmagazine.com/normal-server-response.svg
  2. 2 http://provide.smashingmagazine.com/normal-server-response.svg
  3. 3 http://provide.smashingmagazine.com/server-push-response.svg
  4. 4 http://provide.smashingmagazine.com/server-push-response.svg
  5. 5 https://en.wikipedia.org/wiki/Data_URI_scheme
  6. 6 http://provide.smashingmagazine.com/inlined-content-unopt.svg
  7. 7 http://provide.smashingmagazine.com/caching-unopt.svg
  8. 8 http://provide.smashingmagazine.com/caching-unopt.svg
  9. 9 https://w3c.github.io/preload
  10. 10 https://w3c.github.io/preload/#link-element-interface-extensions
  11. 11 https://nginx.org/en/CHANGES
  12. 12 https://www.smashingmagazine.com/wp-content/uploads/2017/02/chrome-push-indicator-large-opt.png
  13. 13 https://www.smashingmagazine.com/wp-content/uploads/2017/02/chrome-push-indicator-large-opt.png
  14. 14 https://www.smashingmagazine.com/wp-content/uploads/2017/02/push-timing-large-opt.png
  15. 15 https://www.smashingmagazine.com/wp-content/uploads/2017/02/push-timing-large-opt.png
  16. 16 https://www.smashingmagazine.com/wp-content/uploads/2017/02/firefox-push-indicator-large-opt.png
  17. 17 https://www.smashingmagazine.com/wp-content/uploads/2017/02/firefox-push-indicator-800w-opt.png
  18. 18 https://nghttp2.org
  19. 19 https://jeremywagner.me
  20. 20 https://www.sitespeed.io
  21. 21 https://www.npmjs.com
  22. 22 https://www.smashingmagazine.com/2016/10/next-generation-server-compression-with-brotli
  23. 23 https://en.wikipedia.org/wiki/Base64#MIME
  24. 24 https://www.sitespeed.io/documentation/sitespeed.io/configuration
  25. 25 https://jeremywagner.me
  26. 26 https://www.smashingmagazine.com/wp-content/uploads/2017/02/graph-first-paint-800w-opt.png
  27. 27 https://www.smashingmagazine.com/wp-content/uploads/2017/02/graph-first-paint-800w-opt.png
  28. 28 https://www.smashingmagazine.com/wp-content/uploads/2017/02/graph-domcontentloaded-large-opt.png
  29. 29 https://www.smashingmagazine.com/wp-content/uploads/2017/02/graph-domcontentloaded-large-opt.png
  30. 30 https://www.smashingmagazine.com/wp-content/uploads/2017/02/graph-page-load-large-opt.png
  31. 31 https://www.smashingmagazine.com/wp-content/uploads/2017/02/graph-page-load-800w-opt.png
  32. 32 https://httpd.apache.org/docs/2.4/mod/mod_http2.html#h2pushpriority
  33. 33 https://httpd.apache.org/docs/2.4/mod/mod_http2.html#h2pushdiarysize
  34. 34 https://h2o.examp1e.net/configure/http2_directives.html
  35. 35 https://css-tricks.com/cache-aware-server-push
  36. 36 https://tools.ietf.org/html/rfc7540#section-8.2
  37. 37 https://www.filamentgroup.com/lab/modernizing-delivery.html
  38. 38 https://www.igvita.com/2013/06/12/innovating-with-http-2.0-server-push/
  39. 39 https://blog.yoav.ws.
  40. 40 https://jakearchibald.com
  41. 41 https://manning.com/books/web-performance-in-action?a_aid=webopt&a_bid=63c31090
  42. 42 https://manning.com

↑ Back to topTweet itShare on Facebook

Web Development Reading List #177: Getting Started With Components, CT-Header, And New Regular Expressions

artificial intelligence 5291510 1920

Web Development Reading List #177: Getting Started With Components, CT-Header, And New Regular Expressions

From time to time, we need to take some time off, and actually, I’m glad that this reading list is a bit shorter as the ones you’re used to. Because one thing that really stuck with me this week was Eric Karjaluoto’s article.

In his article, he states that, “Taking pride in how busy we are is one of the worst ideas we ever had.” So, how about reading just a few articles this week for a change and then take a complete weekend off to recharge your battery?

Further Reading on SmashingMag: Link

News Link

  • The next major release of Angular, Angular 4.05, is now available. It’s smaller and faster than it’s predecessor and ships flat ES modules.

Concept & Design Link

7
Nathan Curtis shares tips on engaging the entire team to kick off a design library8. (Image credit: Nathan Curtis9)

Security Link

Tizen smartphone13
Security researchers have found 40 unknown vulnerabilities in Tizen14, the operating system that runs on millions of Samsung products. (Image credit: Kārlis Dambrāns15)

Privacy Link

  • In the past, we tended to teach people to use a VPN if they wanted to stay secure. But now we know that by far not all VPN services have good intentions16. Some even inject advertising and privacy-leaking data into your network requests or sell your history to third parties.

JavaScript Link

Work & Life Link

  • Eric Karjaluoto shares why we need to slow down18, and why taking pride in how busy we are is one of the worst ideas we ever had. What if the best thing you can do for your career — and life — is to press pause, set your number one priority, and then rethink your way of working?

And with that, I’ll close for this week. If you like what I write each week, please support me with a donation19 or share this resource with other people. You can learn more about the costs of the project here20. It’s available via email, RSS and online.

— Anselm

Footnotes Link

  1. 1 https://www.smashingmagazine.com/taking-pattern-libraries-next-level/
  2. 2 https://www.smashingmagazine.com/2016/06/designing-modular-ui-systems-via-style-guide-driven-development/
  3. 3 https://www.smashingmagazine.com/2014/10/maximize-your-creative-energy/
  4. 4 https://www.smashingmagazine.com/2015/10/es6-whats-new-next-version-javascript/
  5. 5 https://angularjs.blogspot.de/2017/03/angular-400-now-available.html?m=1
  6. 6 https://medium.com/eightshapes-llc/the-component-cut-up-workshop-1378ae110517?scid=social71322026
  7. 7 https://medium.com/eightshapes-llc/the-component-cut-up-workshop-1378ae110517?scid=social71322026
  8. 8 https://medium.com/eightshapes-llc/the-component-cut-up-workshop-1378ae110517?scid=social71322026
  9. 9 https://medium.com/eightshapes-llc/the-component-cut-up-workshop-1378ae110517?scid=social71322026
  10. 10 https://scotthelme.co.uk/a-new-security-header-expect-ct/
  11. 11 https://arstechnica.com/security/2017/03/smart-tv-hack-embeds-attack-code-into-broadcast-signal-no-access-required/
  12. 12 https://motherboard.vice.com/en_us/article/samsung-tizen-operating-system-bugs-vulnerabilities
  13. 13 https://motherboard.vice.com/en_us/article/samsung-tizen-operating-system-bugs-vulnerabilities
  14. 14 https://motherboard.vice.com/en_us/article/samsung-tizen-operating-system-bugs-vulnerabilities
  15. 15 https://www.flickr.com/photos/janitors/16536562988/in/photolist-rchd3Y-o13k8E-qx56W6-rchVLj-bWV3Kj-hxbrX1-hxaGb4-hxaGqT-bXDr5A-bXDqZ7-6uLqGA-hxaZdm-bXDrvG-hxcvsV-hxcwG8-hxcrEe-bXDrxm-bXDtQJ-bXDtWJ-hxLCix-bXDrz1-bXDr9f-kwodgw-bXDrSN-bXDqW9-dHaR6a-bXDr7W-fH91o3-bXDrcb-bXDsD9-bXDqGN-bXDsxJ-CYBJQS-arcj4y-bXDqUo-bXDrE7-bXDrXL-dmDVf1-bXDrsf-Hyxu6C-bXDrJL-oAK3iw-hxHeKp-oExtQE-hxHZbG-pnCwed-s7oTbE-hxJQr6-hxJZyc-hxLCqg
  16. 16 https://motherboard.vice.com/en_us/article/phony-vpn-services-are-cashing-in-on-americas-war-on-privacy
  17. 17 https://ponyfoo.com/articles/regular-expressions-post-es6
  18. 18 http://blog.officehours.io/slow-the-fuck-down/
  19. 19 https://wdrl.info/donate
  20. 20 https://wdrl.info/costs/

↑ Back to topTweet itShare on Facebook

An Overview Of E-Commerce Platforms

artificial intelligence 5291510 1920

An Overview Of E-Commerce Platforms

Did you know that bandwidth overage charges are (still) a problem and most users prefer not to rely on a developer? Well, I talked to 917 (real-life) users and created a guide to help others find the e-commerce software that suits them best.

I completed this guide by searching for websites built with e-commerce software (you can verify by looking at the source code — certain code strings are unique to the software). Once I found a website, I (or one of my virtual assistants) would email the owner and ask if they’d recommend a particular software. Typically, they’d reply and I’d record their response in a spreadsheet (and personally thank them). Occasionally, I would even go on the phone to speak with them directly (although I quickly found out that this took too much time).

Here’s what I discovered.

Further Reading on SmashingMag: Link

Customer Satisfaction Link

I calculated customer satisfaction by finding the percentage of active users who recommend the software:

E-commerce software Recommendation %
Shopify 98%
Squarespace 94%
Big Cartel 91%
WooCommerce 90%
OpenCart 88%
Jumpseller 86%
GoDaddy 83%
CoreCommerce 80%
BigCommerce 79%
Ubercart 78%
Wix 76%
Magento 74%
Weebly 74%
3dcart 72%
PrestaShop 70%
Goodsie 65%
Spark Pay 65%
Volusion 51%

Shopify is the pretty clear winner, with Squarespace close behind — but both companies are actually complementary. Shopify is a complete, robust solution that works for both small and large stores, while Squarespace is a simple, approachable platform that works well for stores just starting out. (Worth noting: I’ve done similar surveys for portfolio builders5 and landing-page builders6, and Shopify is the only company I’ve seen score higher than 95% in customer satisfaction.)

But looking only at customer satisfaction is not enough. After all, e-commerce platforms have different strengths. So, I also asked users what they like and dislike about their software and found some important insights about each company.

Shopify (98%) Link

What Users Like Link

App store and features

“The best thing is that you don’t need a developer to add features… there’s a ton of apps available.” | “Their partner ecosystem is best.” | “Shopify has any feature under the sun — if you think you need it, someone already created an app.” | “Access to Shopify Apps is great.” | “There’s heaps of third-party apps you can integrate easily that I believe are essential to growing a business.” | “So many third-party apps, templates that other platforms aren’t popular enough to have.” | “There are many apps that can help with customization issues.” | “There are a ton of great third-party apps for extended functionality.”

Ease of use

“Easy to set up without having specific skills.” | “Intuitive user interface.” | “Simple to use.” | “It is very easy to start selling online.” | “Easy UI, pretty intuitive.” | “The interface is excellent for managing e-commerce.” | “It’s really clean and easy to manage.” | “Shopify provides a very straightforward way to add products, edit options and to apply different themes.” | “More than anything, very simple.” | “It’s simple and intuitive.” | “Very user-friendly.” | “Super user-friendly for non-computer guys like myself.” | “The back end is exceptional.”

7
Users love Shopify’s App Store. (View large version8)

Squarespace (94%) Link

What Users Like Link

Ease of use

“It’s very easy to use.” | “The e-commerce is so easy to use.” | “It’s easy to configure, simple to add, delete and modify our inventory, and most importantly it allows us to easily keep track of our ins and outs with helpful metrics and sales graphs.” | “It’s very easy to set up.” | “The user interface is easy to use.” | “Commerce is really nice and easy to set up.” | “Love the interface, very easy to work with.” | “I find it easy to use.” | “It was pretty easy to set up and has been a snap to maintain.” | “It’s all pretty smooth and easy.” | “It’s super-easy.” | “I’ve tried Drupal, WordPress… the interface and creative ability of Squarespace is much superior.”

Templates

“Has some great templates for a good-looking website.” | “Squarespace is an easy way to get a great looking site.” | “The sites are beautiful.” | “The templates and editing features on the blog and site are super-easy.” | “The thing I like most are the beautiful and easy templates.”

What Users Don’t Like Link

Limitations

“The only thing I would say they need to improve is allowing more than one currency on the e-commerce site, which currently is not available.” | “It works pretty good for basic sales of items.” | “There are some limitations in terms of customizing, but they are minor.” | “If you are using it as is and just need the limited feature set that it comes with, it’s a great option.” | “Overall, it’s great for putting a few simple products up, but if you need anything beyond their default cart options, get a proper Squarespace developer or someone to set up a Shopify site for you.” | “It is really a great place to start, but unfortunately a place that is easily transitioned out of once the business begins to grow.”

Shipping

“My partners have had some concerns with the shipping aspect, though.” | “Yes, I would recommend it, but Squarespace needs to have calculated shipping for all the plans.” | “The shipping is still something I wish was a little easier.” | “The only thing I would say is that, for me, the shipping options are more limited than I would like.” | “There are some features I wish were better implemented in the base package (like shipping integration for international orders), but I’d recommend it.”

Squarespace9
Users love Squarespace’s sleek and simple themes. (View large version10)

Big Cartel (91%) Link

What Users Like Link

Good for new stores

“I would recommend Big Cartel for smaller shops.” | “I would recommend it, especially startup users.” | “It’s a great place to start out!” | “We’d recommend it for similar businesses, especially those just getting started.” | “It is a great platform for something really simple and was very easy to set up.” | “Big Cartel is great for beginning stages of a store. We’re actually entertaining moving to a new platform right now.” | “It’s quite good for a small company or startup, for sure.” | “I’m finding that in the early stages of the business, it’s extremely handy for stock listing and very straightforward to use.”

Ease of use

“It’s very easy to use.” | “It’s very easy to use, navigate and customize the shopfront.” | “I am particularly fond of the back end and the admin tools. They make maintaining and shipping products a breeze.” | “It’s super-simple and really user-friendly.” | “I’m not savvy, so it works well for my skill level.” | “Easy to set up… and easy to control and set inventory.” | “They make it so easy to have a beautiful website.” | “For just a few items, Big Cartel totally gets the job done and is user-friendly.”

Price

“I only have to pay $9.99 a month for Big Cartel. That’s a huge perk for me.” | “Low price point and easy to use.” | “The rates are the lowest considering all the things you’re able to do.” | “I have found the cost is a lot better than my Etsy store.” | “You get a great platform for a great price.” | “Compared to Etsy, the fees are ridiculously cheap!” | “One fee a month, no item fees per listing… There is an option to open a store for free with five listings. This is an amazing feature.” | “Their prices are also very reasonable.”

What Users Don’t Like Link

Limitations

“Lacking in features.” | “It is limited in terms of themes… You always know when you’re on a Big Cartel site.” | “It does most of what I expect of it, but also has limitations.” | “The one problem I have is that the only options for receiving payments are PayPal and Stripe.” | “If you want more of an interactive site with blogs and videos and whatnot, I think there are better options out there.” | “We are currently moving over to Shopify because we have maxed out Big Cartel’s limited 300-item store capacity. That is the only downside of Big Cartel.” | “You are limited by what Big Cartel allows you to do. For example, there are certain promotions that I would like to do, but currently Big Cartel has no way of allowing it.”

Big Cartel11
Big Cartel is simple, which makes it easy to use and perfect for stores just starting out. (View large version12)

WooCommerce (90%) Link

What Users Like Link

Extensions

“Many useful plugins for it.” | “So many features.” | “There are plenty of add-ons with it to customize shop as we need.” | “Fully customizable.” | “The plugin architecture is great.” | “It also has a lot of plugins.” | “It’s very good if you are looking for something that can do anything… there are extensions available, and coders who can write plugins.” | “I’m a fan of the plugins because it allows for a lot of customization.”

Ecosystem

“The ecosystem is well supported.” | “Great support with a whole online community dedicated to it.” | “I’m always able to find the answer to any question I have, either through the official WooCommerce knowledge base or in the community forums.”

What Users Don’t Like Link

Developer may be required

“Custom modifications do require somewhat advanced developer knowledge.” | “WooCommerce does require knowledge in website building… At one point, it became extremely slow, and I couldn’t figure out where the problem was.” | “What should be native often requires plugins or coding.” | “Very customizable with some code editing.” | “WooCommerce definitely requires a solid knowledge of the inner workings.” | “There definitely is a learning curve, but it is not too hard to master.” | “It had to be highly customized for us by our website developers.”

WooCommerce13
WooCommerce users love the huge selection of extensions they can add to their stores. (View large version14)

OpenCart (88%) Link

What Users Like Link

Extensions

“There are plenty of extensions (free and for purchase).” | “Tons of extensions to make it really awesome.” | “OpenCart extensions… have been very valuable and reliable.” | “Customization does need IT capabilities, though.” | “The software is only as good as its implementers.”

What Users Don’t Like Link

Often requires a developer

“It took some PHP programming to get it completely as we wish, but now it works fine and suits my goals well.” | “If you do not have someone capable of working behind the scenes, it would be difficult to manage.” | “I’d recommend it if and only if you have at least some knowledge web programming (PHP, JavaScript, XML, MySQL, etc.).” | “Not recommended for anyone without some web programming knowledge.” | “With the right technical staff, yes I would.” | “If you would be a serious user, I can recommend OpenCart, but also I would recommend hiring a developer to make all custom improvements.” | “Yes, I would recommend it as a good platform with cheap extensions.” | “There is also a large amount of high-quality extensions.” | “Tons of plugins, both free to paid.”

Extensions can create bugs

“When you modify it, it does amazing things but is super-finicky.” | “Buying and installing extensions is a bad idea… It’s not a plug-and-play procedure.” | “As we grew bigger, there have been headaches, mostly to do with third-party extensions clashing with each other.”

OpenCart15
OpenCart offers a large marketplace of extensions, which users love. (View large version16)

Jumpseller (86%) Link

What Users Like Link

Customer support

“The Jumpseller team is also very helpful… They’ll walk you through the process of making website [changes], so you can really understand.” | “Technical support is great, always helpful and fast.” | “The best thing is its excellent service, very fast and efficient.” | “Support has worked well so far. When we’ve submitted a query, we’ve gotten quick feedback.” | “Fast and good email support.” | “The customer service is very responsive and helpful.” | “The email response time is super-fast. If I have one question or doubt regarding anything, from design to DNS configuration, they’ll reply in less than 15 minutes!”

Using it for Chilean and international stores

“Our store is based in Chile, and another feature we appreciated is that it had full integration with local payment systems.” | “Has local credit-card options (in our country).” | “Recently, they integrated the price list of one of the shipping companies most used in our country.” | “The good thing is the translation tool.” | “I can tell you that we have selected Jumpseller because we are selling in Chile, and the store was very well integrated with the most popular payment methods, couriers, etc.”

Jumpseller17
Users recommend Jumpseller for managing languages and international stores. (View large version18)

GoDaddy (83%) Link

What Users Like Link

Ease of use

“It is easy to set up.” | “Easy to maintain.” | “Fairly user-friendly.” | “They really made everything so simple to make extremely intuitive changes quickly.” | “It’s easy to work with.” | “I would recommend it for a new user because of the ease of use in building a store.” | “Easy to use and have had no issues.”

What Users Don’t Like Link

Limitations

“There are design limitations, though.” | “It is lacking in several business customization respects.” | “I wish there was a little more customization allowed.” | “There are some design limitations unless you know HTML.” | “Product is good but has many limitations.” | “I like it, but it does have limitations.” | “It has some limitations, but I have been able to work around them.” | “It does have its limitations on customizing, though.”

Credit-card processor options

“It would be better if it allowed shoppers to use a credit card to place an order, even if we don’t use their approved credit-card processor.” | “We were happy with them for years, and then out of the blue, the payment processors affiliated with GoDaddy dropped us.” | “We will be switching all of our stores from GoDaddy in the near future because it does not allow you to use the merchant service of your choice. You are forced to use Stripe.”

GoDaddy19
Users found GoDaddy easy to use, though limited. (View large version20)

CoreCommerce (80%) Link

What Users Like Link

Support

“Tech support has always been responsive and friendly.” | “Good customer support.” | “I have been able to live chat or call with questions without issue.” | “The support is excellent.” | “Very quick responses to any of our requests.” | “Their support is very good.” | “Their customer service is absolutely the very best.” | “You can always call them 24/7 if you need any kind of support, and it doesn’t cost any extra money.” | “Their tech support is awesome.” | “Tech support has always been responsive and friendly.” | “CoreCommerce’s service is good. It has a mom and pop feel to it.”

Price

“Price for the features and benefits given is exceptional, and no one we’ve spoken with can come close to the value.” | “It is a very cost-effective solution.” | “It is also very affordable.” | “I have yet to find another platform that offers the same value as CoreCommerce (at least for our particular business).” | “Prices are good.”

What Users Don’t Like Link

Feels outdated

“Technologies are old, and they are very slow to update it.” | “It feels like the year 2003.” | “Outdated and uninspiring admin panel.” | “They’ve been a bit behind the times with integrations (still no Bitcoin, for example).” | “They are using an antiquated system, which doesn’t bode well for tie-in structures for the future.”

Difficult to use

“I do find the GUI to be somewhat frustrating and unintuitive.” | “It is annoying when you [have] to update each thing in multiple areas.” | “It is not intuitive or user-friendly.” | “The product was flaky. Flexible but badly designed in lots of areas.” | “Control panel sucks.”

CoreCommerce21
Users found CoreCommerce difficult to use. (View large version22)

BigCommerce (79%) Link

What Users Like Link

Customer support

“I emailed the president [of BigCommerce] at 1:00 am requesting help… Within 10 minutes, [he] was on it with compassion and ready to help. They have bent over backward for me.” | “They provide excellent customer support.” | “If nothing else, they seem to have great customer service.” | “More than anything, we care about customer service, and BigCommerce provides excellent customer service.” | “Technical support has been great.” | “Great support.” | “Their tech support is 24/7 and is very responsive to our questions.” | “Customer service… is very helpful.”

What Users Don’t Like Link

Price

“Their pricing structure is punitive for successful businesses… This is surely a recurring theme if you’ve reached out to many B2C website users who have grown their site.” | “A bit pricey when your sales hit over $300,000 a year.” | “[Recently,] my monthly payments increased from $25 to $250 due to my business exceeding the annual sales of their intermediate plan.” | “Because of our sales volume, BigCommerce frequently increases our monthly fees based on increasing sales. This has become very expensive.” | “A bit pricey.” | “We feel it is overpriced these days.” | “Their pricing structure makes no sense, but I’ve been with them for seven years.” | “I would recommend BigCommerce. Pricing is a bit high, though.” | “I personally think the pricing is a little steep.”

BigCommerce23
Managing products in BigCommerce (View large version24)

Ubercart (78%) Link

What Users Don’t Like Link

Not for non-developers

“Not as friendly for a non-developer or an individual who just wants to set up shop on their own and doesn’t have a technical background.” | “Ubercart works well as long as you have an experienced programmer.” | “Please note that it would require a developer who knows Drupal, because many aspects needed customization.” | “[I would recommend it ] if you’re comfortable with Drupal.”

Difficult to use

“Ubercart is OK, but it is hard to customize.” | “The learning curve is quite steep.” | “It can be a bit tricky to get your store looking just the way you want.” | “Ubercart isn’t the easiest to set up or work with.” | “The only disadvantage of Ubercart is the complex configuration of the store system.” | “It’s not as plug-and-play as Shopify.”

Ubercart25
Users found that Ubercart works best if you have a developer on your team. (View large version26)

Wix (78%) Link

What Users Like Link

Ease of use

“The e-commerce site is beyond simple to use.” | “I would recommend it on one level: It’s easy to use. I can do all the building and updating myself, and so that’s good.” | “Easy to use.” | “Easy to build and maintain.” | “It is user-friendly, easy to set up and modify.” | “It’s super-easy to use, and it seems like everyone who’s ordered from me has also done so with ease.” | “If you want a simple storefront, it’s pretty straightforward, easy and cheap.” | “It is easy to set up.” | “It’s easy to use and user-friendly.” | “It was pretty intuitive to set up.”

What Users Don’t Like Link

Limitations

“It is basic.” | “There are some limitations with shipping and accounting (sending to QuickBooks, etc.).” | “A little limited in some options.” | “I have not been able to make it work in the way I need.” | “I cannot update the inventory amount.” | “We had so many different options, which the configuration of the store and products did not allow us to do.” | “We also wanted to be able to get customers reviews and could not do it.” | “My main complaint is the lack of customization options — for example, not being able to display a price per pound.” | “If you want a variety of options and a wide range of modifications, it is not ideal.”

Wix27
Users found Wix easy to use but limited. (View large version28)

Magento (74%) Link

What Users Like Link

Highly customizable

“We have complete control over our Magento store and have customized it extensively to meet our needs. That’s what I like most about it.” | “The amount of customizations and extensions available are endless.” | “It has an unparalleled level of customization and freedom.” | “It has a lot of great customization features.” | “It’s pretty powerful.”

What Users Don’t Like Link

Difficult to use

“Probably the steepest learning curve.” | “It’s very expensive to get changes made.” | “Magento is overkill for what I need to do on my site.” | “User interface is not as easy as it could be.” | “It can be a real pain sometimes.” | “Complicated to set up.” | “It’s got a steep learning curve.” | “Magento has a huge learning curve.” | “It breaks for no reasons, and it breaks if you add anything to the site.” | “Always something going wrong for no apparent reason.”

Often requires professional help

“You will need a good PHP programmer if you intend to add anything to it beyond the default installation.” | “If one wants to really change Magento, one needs an expert.” | “Needs a good specialist to partner with to get the best out of it.” | “I would recommend it as long as you have a true Magento-certified developer to hold your hand the entire way and to create your site and work with you.” | “Magento is good if you’re a web developer and have coding skills.”

Magento29
Users found Magento difficult to use. (View large version30)

Weebly (74%) Link

What Users Like Link

Ease of use

“It is very easy to use.” | “It was easy to use without web design experience.” | “It is basic and easy to use.” | “I have enjoyed the ease of Weebly and what you can accomplish with the tools.” | “It is extremely easy for me to use.” | “I’d recommend it because it is so easy to set up and track inventory.” | “This is one of the easiest [e-commerce platforms] I have used.” | “I do like the online store with Weebly because of the ease of use.” | “Weebly is really easy to use.”

What Users Don’t Like Link

Third-party hosts

“[Weebly] is offered through MacHighway, which I use for my hosting, so there were some glitches in the beginning that probably wouldn’t have been there if I’d gone straight through Weebly.” | “Just make sure you buy the Weebly subscription directly through weebly.com and not through a reseller, because I lost a whole website that way.” | “I would recommend it but only through the Weebly host.” | “The B.S. part is that since day one, iPower (a third-party Weebly host) claimed I was getting an ultra-premium package but was only paying for basic. I would go to edit a product and nothing worked. I’d call customer support and they’d tell me I need to upgrade. This has happened to me twice in three years with them. I’m hoping they get stuck with a class-action suit for fraud.” | “iPage is my host for Weebly. Because of this, I don’t have access to all of the features Weebly offers.” | “… Full access to all of the Weebly features would sort that at once, but iPage (maybe I should change) wants to lock me in for three years and pay the full amount up front!”

Limited features

“If you want a more customizable tool, then this might not work for you.” | “Weebly is missing some of the critcal things that we want from an online store.” | “I am hoping that they have, or will come up with, an automatic shipping calculation.” | “The only hiccup is when I need to change my prices. I have a lot of inventory, and I have found that the easiest way (relatively speaking) to do this is to change each one individually.” | “You can’t do everything design-wise on it.” | “It was perfect for me at first, but I have grown out of it very quickly [because of limited features].” | “The Weebly platform is not scalable. There is no element to customize your cart.” | “The shipping is a problem because it can’t be adjusted for lighter, heavier or multiple items.”

Weebly31
Users found Weebly easy to use but limited. (View large version32)

3dcart (72%) Link

What Users Don’t Like Link

Bandwidth overage charges

“If you read the forums, one problem that continually arises, and one that I have, is bandwidth. It seems that I’m always going over my bandwidth, even though I have relatively few products and dump files regularly.” | “3dcart charges for bandwidth, so serving lots of digital products from your server might not be a great idea depending on your budget.” | “They charge you for data, and it adds up.” | “It tends to use a lot of bandwidth. My store doesn’t have a huge amount of traffic (yet!), but I still go over my plan just about every month.”

Customer support

“Their comments are snarky, and their help is judgemental in that they always place blame on the customer, and it can take up to a week for them to solve a problem.” | “”Customer support has a laissez-faire attitude.” | “I have to really keep on them when I open a ticket, or I may not get a response for days.” | “I would say the biggest con has been customer service.” | “I would characterize them as almost disrespectful.” | “Their lack of support [was surprising].” | “The tech support also cannot help with even the most basic HTML questions.” | “Technical support online isn’t the best.” | “The help line is not very helpful. If there is a problem, such as the system stops taking orders or accepting credit cards, they assume it’s a problem on your end.” | “Their live support sucks.”

Difficult to use

“I feel the product is terribly cumbersome.” | “The admin interface makes it very difficult to find what settings I’m looking for.” | “It is awkward and not very user-friendly.” | “My website is with 3dcart, but it is overwhelming.” | “It is a little quirky in the back end.” | “I personally find it difficult to make even simple changes to.” | “Some of it is not very intuitive, so you have to keep clicking around until you remember where everything is.”

3dcart33
Users found 3dcart difficult to use and were frustrated with the bandwidth overage charges. (View large version34)

PrestaShop (70%) Link

What Users Like Link

Modules

“It has quite a lot of modules.” | “It has loads of modules” | “Lots of additional modules and functionalities to add.” | “A lot of modules.” | “They have a lot of free and already installed modules.” | “There are a lot of free modules.” | “Large offer of modules.”

What Users Don’t Like Link

Difficult to use

“You need to be quite a good geek to understand everything.” | “We’ve encountered and still are encountering lots of problems with PrestaShop.” | “PrestaShop isn’t as user-friendly as others are nowadays.” | “The admin panel is not user-friendly.” | “I don’t recommend it for a beginner or if you don’t have much technical skill.”

Buggy

“I hate it… It’s buggy and impossible to upgrade easily to newer versions.” | “It’s kind of an unstable, slow system for me, but I think in the near future it will be more stable and fast.” | “We have lots of problems with PrestaShop.” | “No, I would not recommend it. Buggy as hell.” | “No, I would not recommend it. Too heavy and too slow.” | “The back-end pages sometimes take an age to load — even for simple stuff.”

PrestaShop35
Users found PrestaShop buggy at times. (View large version36)

Goodsie (65%) Link

What Users Like Link

Good for beginners

“Quick and easy. I think its simplicity best suits the light or new user.” | “Great for people with no knowledge [of how to build a store].” | “For someone with zero experience building a website, I found their product to be so easy to navigate.” | “I highly recommend it for beginners.”

What Users Don’t Like Link

Pricing

“Way too expensive.” | “There are cheaper options out there that do the same thing.” | “I liked Goodsie when I started with them five or six years ago, but their prices keep going up.” | “Prices were hiked above what they should be, so I am about to change.” | “The price went from $15 to $30 per month not too long ago.”

Goodsie37
Users suggest Goodsie’s simplicity makes it good for beginners, although it is expensive. (View large version38)

Spark Pay (65%) Link

What Users Like Link

Customer support is prompt

“Whenever we’ve needed support, their help systems are very responsive.” | “Spark Pay’s technical support is excellent.” | “Very responsive for help.” | “They have been responsive to any needs I’ve had.” | “I find their customer service to be quite responsive.” | “Tech support is very responsive via phone or email.” | “They have been very responsive to helping out with general website questions and problems.”

What Users Don’t Like Link

Bandwidth overage charges

“The main thing I don’t like are the extra bandwidth charges.” | “Nailed with huge bandwidth charges.” | “They are little hidden fees for going over your bandwidth account file storage and product count if you don’t keep an eye on them.”

Difficult to use

“Spark Pay is not simple!” | “They have a ton of features built in — most of them are half-baked and don’t function 100%, which has led to frustration.” | “[Needs to] reduce the bloat in their software.” | “Unless you have a designer and/or developer on staff, or at the very least a very computer-savvy non-techie, it’s virtually impossible to understand Spark Pay.” | “Their web editor is clumsy.” | “Their platform is buggy.” | “It is crazy complicated to make even some of the most mundane changes.” | “Their system bogs down so much that only the most minor of changes are doable.” | “Clunky UI, way too much complexity. Just a nightmare to deal with.”

While prompt, customer support can be disappointing

“There service desk really isn’t one. They have no formal (or competent) escalation process.” | “They are not nearly as responsive to fixing significant issues as they should be.” | “I feel like the platform has a lot of tools to offer, but few resources to teach you how to use them.” | “Technical support is rather lacking. When you do finally get someone to answer the tickets, they do a very minimal amount of work and effort to correct the problem.”

Spark Pay39
Users found Spark Pay difficult to use and were frustrated by bandwidth overage charges. (View large version40)

Volusion (51%) Link

What Users Like Link

Customer support

“Their technical support department people are top-notch… I’m extremely impressed with them.” | “The [support] team at Volusion is knowledgeable, and that is highly important.” | “Their customer support is excellent.” | “Their support is superb.” | “Support is second to none.” | “There technical support team is also very good in helping to fix any issues that we might have had.”

What Users Don’t Like Link

Bandwidth limitations

“The one thing I can’t stand is the amount of bandwidth they provide you with. [It] will easily be gone in a week if you have a lot of visitors.” | “They don’t have adequate bandwidth plans, and their billing for bandwidth overages is highly irritating.” | “Site traffic is pricey.” | “I originally used very large images for my products and received some rather stiff hosting fines for going over the stupidly low bandwidth level.” | “The way they charge for bandwidth caused us to have obscene overage charged for months.”

Expensive

“It is particularly expensive, and the costs weren’t clear [when we started].” | “Once the site is built, they nickel and dime you for every little thing imaginable.” | “I also used the Volusion SEO team and that was a joke. $1600 a month!” | “Not the least expensive around.” | “I would caution new users to be aware of hidden costs. Email addresses are extra. An SSL certificate is extra. A service to check the reliability of each credit card is extra. SEO and design services are phenomenally expensive.” | “Going by the prices they charge for SEO packages, they’re aiming at companies far larger than mine.” | “If you want anything besides barebone offerings, everything else is available… for a price.” | “I just wish it was a little cheaper.” | “Volusion keeps [the initial setup and customization] complicated, hoping that you will pay them to do it for you.”

Difficult to use

“The back end is not user-friendly.” | “The UX is confusing and bloated, but I’m used to it.” | “There is a learning curve, so it takes a while to get going. And if you want customization, be prepared to learn it yourself or pay some hefty fees.” | “It’s not straightforward and is prone to errors.” | “If you change a font size within the text, you then lose all other formatting — nothing major, but annoying and time-consuming.” | “It’s quite clunky to manage content and design.” | “There are random glitches throughout the site that have probably cost me thousands in abandoned carts.” | “One thing that is hard for me is manipulating website elements. GoDaddy was easier for me.”

Volusion41
Users found Volusion difficult to use and expensive. (View large version42)

Conclusion Link

It’s worth noting that this is not a list of all e-commerce software currently available in the world. Instead, I’ve only included software for which I was able to talk to a minimum of 30 users (and I was not able to find 30 users for several companies).

But this is a fairly comprehensive list of the most popular e-commerce platforms. Furthermore, these are the thoughts of real, verified users. I hope it’s helpful in your search for the right e-commerce software!

This article is based off of the e-commerce software guide originally published here43.

(vf, al, il)

Footnotes Link

  1. 1 https://www.smashingmagazine.com/2014/10/reducing-abandoned-shopping-carts/
  2. 2 https://www.smashingmagazine.com/2013/11/guidelines-navigation-categories-ecommerce-study/
  3. 3 https://www.smashingmagazine.com/2013/03/designing-a-better-mobile-checkout-process/
  4. 4 https://www.smashingmagazine.com/2011/04/taking-credit-card-payments-online-whats-involved/
  5. 5 https://www.wisebuyer.com/portfolio-builders
  6. 6 https://www.wisebuyer.com/landing-page-builders
  7. 7 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Shopify-large-opt.jpg
  8. 8 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Shopify-large-opt.jpg
  9. 9 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Squarespace-large-opt.jpg
  10. 10 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Squarespace-large-opt.jpg
  11. 11 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Big-Cartel-large-opt.jpg
  12. 12 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Big-Cartel-large-opt.jpg
  13. 13 https://www.smashingmagazine.com/wp-content/uploads/2017/03/WooCommerce-large-opt.png
  14. 14 https://www.smashingmagazine.com/wp-content/uploads/2017/03/WooCommerce-large-opt.png
  15. 15 https://www.smashingmagazine.com/wp-content/uploads/2017/03/OpenCart-large-opt.png
  16. 16 https://www.smashingmagazine.com/wp-content/uploads/2017/03/OpenCart-large-opt.png
  17. 17 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Jumpseller-large-opt.jpeg
  18. 18 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Jumpseller-large-opt.jpeg
  19. 19 https://www.smashingmagazine.com/wp-content/uploads/2017/03/GoDaddy-large-opt.jpg
  20. 20 https://www.smashingmagazine.com/wp-content/uploads/2017/03/GoDaddy-large-opt.jpg
  21. 21 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Core-Commerce-large-opt.jpg
  22. 22 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Core-Commerce-large-opt.jpg
  23. 23 https://www.smashingmagazine.com/wp-content/uploads/2017/03/BigCommerce-large-opt.jpg
  24. 24 https://www.smashingmagazine.com/wp-content/uploads/2017/03/BigCommerce-large-opt.jpg
  25. 25 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Ubercart-large-opt.png
  26. 26 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Ubercart-large-opt.png
  27. 27 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Wix-large-opt.jpg
  28. 28 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Wix-large-opt.jpg
  29. 29 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Magento-large-opt.png
  30. 30 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Magento-large-opt.png
  31. 31 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Weebly-large-opt.jpg
  32. 32 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Weebly-large-opt.jpg
  33. 33 https://www.smashingmagazine.com/wp-content/uploads/2017/03/3dcart-large-opt.jpg
  34. 34 https://www.smashingmagazine.com/wp-content/uploads/2017/03/3dcart-large-opt.jpg
  35. 35 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Prestashop-large-opt.png
  36. 36 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Prestashop-large-opt.png
  37. 37 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Goodsie-large-opt.png
  38. 38 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Goodsie-large-opt.png
  39. 39 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Spark-Pay-large-opt.jpg
  40. 40 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Spark-Pay-large-opt.jpg
  41. 41 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Volusion-large-opt.jpeg
  42. 42 https://www.smashingmagazine.com/wp-content/uploads/2017/03/Volusion-large-opt.jpeg
  43. 43 https://www.wisebuyer.com/ecommerce-software

↑ Back to topTweet itShare on Facebook

Creating One Browser Extension For All Browsers: Edge, Chrome, Firefox, Opera, Brave And Vivaldi

artificial intelligence 5291510 1920

Sponsored PostCreating One Browser Extension For All Browsers: Edge, Chrome, Firefox, Opera, Brave And Vivaldi

In today’s article, we’ll create a JavaScript extension that works in all major modern browsers, using the very same code base. Indeed, the Chrome extension model based on HTML, CSS and JavaScript is now available almost everywhere, and there is even a Browser Extension Community Group1 working on a standard.

I’ll explain how you can install this extension that supports the web extension model (i.e. Edge, Chrome, Firefox, Opera, Brave and Vivaldi), and provide some simple tips on how to get a unique code base for all of them, but also how to debug in each browser.

Note: We won’t cover Safari in this article because it doesn’t support the same extension model2 as others.

Further Reading on SmashingMag: Link

Basics Link

I won’t cover the basics of extension development because plenty of good resources are already available from each vendor:

So, if you’ve never built an extension before or don’t know how it works, have a quick look at those resources. Don’t worry: Building one is simple and straightforward.

Our Extension Link

Let’s build a proof of concept — an extension that uses artificial intelligence (AI) and computer vision to help the blind analyze images on a web page.

We’ll see that, with a few lines of code, we can create some powerful features in the browser. In my case, I’m concerned with accessibility on the web and I’ve already spent some time thinking about how to make a breakout game accessible using web audio and SVG14, for instance.

Still, I’ve been looking for something that would help blind people in a more general way. I was recently inspired while listening to a great talk by Chris Heilmann15 in Lisbon: “Pixels and Hidden Meaning in Pixels16.”

Indeed, using today’s AI algorithms in the cloud, as well as text-to-speech technologies, exposed in the browser with the Web Speech API17 or using a remote cloud service, we can very easily build an extension that analyzes web page images with missing or improperly filled alt text properties.

My little proof of concept simply extracts images from a web page (the one in the active tab) and displays the thumbnails in a list. When you click on one of the images, the extension queries the Computer Vision API to get some descriptive text for the image and then uses either the Web Speech API or Bing Speech API to share it with the visitor.

The video below demonstrates it in Edge, Chrome, Firefox, Opera and Brave.

You’ll notice that, even when the Computer Vision API is analyzing some CGI images, it’s very accurate! I’m really impressed by the progress the industry has made on this in recent months.

I’m using these services:

  • Computer Vision API18, Microsoft Cognitive Services

    This is free to use19 (with a quota). You’ll need to generate a free key; replace the TODO section in the code with your key to make this extension work on your machine. To get an idea of what this API can do, play around with it20.
  • 21
  • Bing Text to Speech API22, Microsoft Cognitive Services

    This is also free to use23 (with a quota, too). You’ll need to generate a free key again. We’ll also use a small library24 that I wrote recently to call this API from JavaScript. If you don’t have a Bing key, the extension will always fall back to the Web Speech API, which is supported by all recent browsers.

But feel free to try other similar services:

You can find the code for this small browser extension on my GitHub page27. Feel free to modify the code for other products you want to test.

Tip To Make Your Code Compatible With All Browsers Link

Most of the code and tutorials you’ll find use the namespace chrome.xxx for the Extension API (chrome.tabs, for instance).

But, as I’ve said, the Extension API model is currently being standardized to browser.xxx, and some browsers are defining their own namespaces in the meantime (for example, Edge is using msBrowser).

Fortunately, most of the API remains the same behind the browser. So, it’s very simple to create a little trick to support all browsers and namespace definitions, thanks to the beauty of JavaScript:

window.browser = (function () { return window.msBrowser || window.browser || window.chrome; })(); 

And voilà!

Of course, you’ll also need to use the subset of the API supported by all browsers. For instance:

Extension Architecture Link

Let’s review together the architecture of this extension. If you’re new to browser extensions, this should help you to understand the flow.

Let’s start with the manifest file31:

Slide132
(View large version33)

This manifest file and its associated JSON is the minimum you’ll need to load an extension in all browsers, if we’re not considering the code of the extension itself, of course. Please check the source34 in my GitHub account, and start from here to be sure that your extension is compatible with all browsers.

For instance, you must specify an author property to load it in Edge; otherwise, it will throw an error. You’ll also need to use the same structure for the icons. The default_title property is also important because it’s used by screen readers in some browsers.

Here are links to the documentation to help you build a manifest file that is compatible everywhere:

The sample extension used in this article is mainly based on the concept of the content script38. This is a script living in the context of the page that we’d like to inspect. Because it has access to the DOM, it will help us to retrieve the images contained in the web page. If you’d like to know more about what a content script is, Opera39, Mozilla40 and Google41 have documentation on it.

Our content script42 is simple:

Slide243
(View large version44)
console.log("Dare Angel content script started"); browser.runtime.onMessage.addListener(function (request, sender, sendResponse) { if (request.command == "requestImages") { var images = document.getElementsByTagName('img'); var imagesList = []; for (var i = 0; i  64 && images[i].height > 64)) { imagesList.push({ url: images[i].src, alt: images[i].alt }); } } sendResponse(JSON.stringify(imagesList)); } }); view raw 

This first logs into the console to let you check that the extension has properly loaded. Check it via your browser’s developer tool, accessible from F12, Control + Shift + I or ⌘ + ⌥ + I.

It then waits for a message from the UI page with a requestImages command to get all of the images available in the current DOM, and then it returns a list of their URLs if they’re bigger than 64 × 64 pixels (to avoid all of the pixel-tracking junk and low-resolution images).

Slide345
(View large version46)

The popup UI page47 we’re using is very simple and will display the list of images returned by the content script inside a flexbox container48. It loads the start.js script, which immediately creates an instance of dareangel.dashboard.js49 to send a message to the content script to get the URLs of the images in the currently visible tab.

Here’s the code that lives in the UI page, requesting the URLs to the content script:

browser.tabs.query({ active: true, currentWindow: true }, (tabs) => { browser.tabs.sendMessage(tabs[0].id, { command: "requestImages" }, (response) => { this._imagesList = JSON.parse(response); this._imagesList.forEach((element) => { var newImageHTMLElement = document.createElement("img"); newImageHTMLElement.src = element.url; newImageHTMLElement.alt = element.alt; newImageHTMLElement.tabIndex = this._tabIndex; this._tabIndex++; newImageHTMLElement.addEventListener("focus", (event) => { if (COMPUTERVISIONKEY !== "") { this.analyzeThisImage(event.target.src); } else { var warningMsg = document.createElement("div"); warningMsg.innerHTML = "

Please generate a Computer Vision key in the other tab. Link

"; this._targetDiv.insertBefore(warningMsg, this._targetDiv.firstChild); browser.tabs.create({ active: false, url: "https://www.microsoft.com/cognitive-services/en-US/sign-up?ReturnUrl=/cognitive-services/en-us/subscriptions?productId=%2fproducts%2f54d873dd5eefd00dc474a0f4" }); } }); this._targetDiv.appendChild(newImageHTMLElement); }); }); });

We’re creating image elements. Each image will trigger an event if it has focus, querying the Computer Vision API for review.

This is done by this simple XHR call:

analyzeThisImage(url) { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = () => { if (xhr.readyState == 4 && xhr.status == 200) { var response = document.querySelector('#response'); var reponse = JSON.parse(xhr.response); var resultToSpeak = `With a confidence of ${Math.round(reponse.description.captions[0].confidence * 100)}%, I think it's ${reponse.description.captions[0].text}`; console.log(resultToSpeak); if (!this._useBingTTS || BINGSPEECHKEY === "") { var synUtterance = new SpeechSynthesisUtterance(); synUtterance.text = resultToSpeak; window.speechSynthesis.speak(synUtterance); } else { this._bingTTSclient.synthesize(resultToSpeak); } } }; xhr.onerror = (evt) => { console.log(evt); }; try { xhr.open('POST', 'https://api.projectoxford.ai/vision/v1.0/describe'); xhr.setRequestHeader("Content-Type", "application/json"); xhr.setRequestHeader("Ocp-Apim-Subscription-Key", COMPUTERVISIONKEY); var requestObject = { "url": url }; xhr.send(JSON.stringify(requestObject)); } catch (ex) { console.log(ex); } } view raw 

The following articles will you help you to understand how this Computer Vision API works:

  • Analyzing an Image Version 1.050,” Microsoft Cognitive Services
  • Computer Vision API, v1.051,” Microsoft Cognitive Services

    This shows you via an interactive console in a web page how to call the REST API with the proper JSON properties, and the JSON object you’ll get in return. It’s useful to understand how it works and how you will call it.

In our case, we’re using the describe feature of the API. You’ll also notice in the callback that we will try to use either the Web Speech API or the Bing Text-to-Speech service, based on your options.

Here, then, is the global workflow of this little extension:

Slide452
(View large version53)

Loading The Extension In Each Browser Link

Let’s review quickly how to install the extension in each browser.

Prerequisites Link

Download or clone my small extension54 from GitHub somewhere to your hard drive.

Also, modify dareangel.dashboard.js to add at least a Computer Vision API key. Otherwise, the extension will only be able to display the images extracted from the web page.

Microsoft Edge Link

First, you’ll need at least a Windows 10 Anniversary Update (OS Build 14393+) to have support for extensions in Edge.

Then, open Edge and type about:flags in the address bar. Check the “Enable extension developer features.”

EnableInEdge00155

Click on “…” in the Edge’s navigation bar and then “Extensions” and then “Load extension,” and select the folder where you’ve cloned my GitHub repository. You’ll get this:

56

Click on this freshly loaded extension, and enable “Show button next to the address bar.”

EnableInEdge00357

Note the “Reload extension” button, which is useful while you’re developing your extension. You won’t be forced to remove or reinstall it during the development process; just click the button to refresh the extension.

Navigate to BabylonJS626158, and click on the Dare Angel (DA) button to follow the same demo as shown in the video.

Google Chrome, Opera, Vivaldi Link

In Chrome, navigate to chrome://extensions. In Opera, navigate to opera://extensions. And in Vivaldi, navigate to vivaldi://extensions. Then, enable “Developer mode.”

Click on “Load unpacked extension,” and choose the folder where you’ve extracted my extension.

Chrome00159
(View large version60)

Navigate to BabylonJS626158, and open the extension to check that it works fine.

Mozilla Firefox Link

You’ve got two options here. The first is to temporarily load your extension, which is as easy as it is in Edge and Chrome.

Open Firefox, navigate to about:debugging and click “Load Temporary Add-on.” Then, navigate to the folder of the extension, and select the manifest.json file. That’s it! Now go to BabylonJS626158 to test the extension.

Firefox00163
(View large version64)

The only problem with this solution is that every time you close the browser, you’ll have to reload the extension. The second option would be to use the XPI packaging. You can learn more about this in “Extension Packaging65” on the Mozilla Developer Network.

Brave Link

The public version of Brave doesn’t have a “developer mode” embedded in it to let you load an unsigned extension. You’ll need to build your own version of it by following the steps in “Loading Chrome Extensions in Brave66.”

As explained in that article, once you’ve cloned Brave, you’ll need to open the extensions.js file in a text editor. Locate the lines below, and insert the registration code for your extension. In my case, I’ve just added the two last lines:

 // Manually install the braveExtension and torrentExtension extensionInfo.setState(config.braveExtensionId, extensionStates.REGISTERED) loadExtension(config.braveExtensionId, getExtensionsPath('brave'), generateBraveManifest(), 'component') extensionInfo.setState('DareAngel', extensionStates.REGISTERED) loadExtension('DareAngel', getExtensionsPath('DareAngel/')) view raw 

Copy the extension to the app/extensions folder. Open two command prompts in the browser-laptop folder. In the first one, launch npm run watch, and wait for webpack to finish building Brave’s Electron app. It should say, “webpack: bundle is now VALID.” Otherwise, you’ll run into some issues.

Brave00167
(View large version68)

Then, in the second command prompt, launch npm start, which will launch our slightly custom version of Brave.

In Brave, navigate to about:extensions, and you should see the extension displayed and loaded in the address bar.

Brave00269
(View large version70)

Debugging The Extension In Each Browser Link

Tip for all browsers: Using console.log(), simply log some data from the flow of your extension. Most of the time, using the browser’s developer tools, you’ll be able to click on the JavaScript file that has logged it to open it and debug it.

Microsoft Edge Link

To debug the client script part, living in the context of the page, you just need to open F12. Then, click on the “Debugger” tab and find your extension’s folder.

Open the script file that you’d like to debug — dareangel.client.js, in my case — and debug your code as usual, setting up breakpoints, etc.

DebugInEdge00171
(View large version72)

If your extension creates a separate tab to do its job (like the Page Analyzer73, which our Vorlon.js74 team published in the store), simply press F12 on that tab to debug it.

DebugInEdge00275
(View large version76)

If you’d like to debug the popup page, you’ll first need to get the ID of your extension. To do that, simply go into the property of the extension and you’ll find an ID property:

DebugInEdge00377

Then, you’ll need to type in the address bar something like ms-browser-extension://ID_of_your_extension/yourpage.html. In our case, it would be ms-browser-extension://DareAngel_vdbyzyarbfgh8/dashboard.html. Then, simply use F12 on this page:

DebugInEdge00478
(View large version79)

Google Chrome, Opera, Vivaldi, Brave Link

Because Chrome and Opera rely on the same Blink code base, they share the same debugging process. Even though Brave and Vivaldi are forks of Chromium, they also share the same debugging process most of the time.

To debug the client script part, open the browser’s developer tools on the page that you’d like to debug (pressing F12, Control + Shift + I or ⌘ + ⌥ + I, depending on the browser or platform you’re using).

Then, click on the “Content scripts” tab and find your extension’s folder. Open the script file that you’d like to debug, and debug your code just as you would do with any JavaScript code.

DebugInChrome00180
(View large version81)

To debug a tab that your extension would create, it’s exactly the same as with Edge: Simply use the developer tools.

DebugInChrome00282
(View large version83)

For Chrome and Opera, to debug the popup page, right-click on the button of your extension next to the address bar and choose “Inspect popup,” or open the HTML pane of the popup and right-click inside it to “Inspect.” Vivaldi only supports right-click and then “Inspect” inside the HTML pane once opened.

DebugInChrome00384
(View large version85)

For Brave, it’s the same process as with Edge. You first need to find the GUID associated with your extension in about:extensions:

BraveDebug00186

And then, in a separate tab, open the page you’d like to debug like — in my case, chrome-extension://bodaahkboijjjodkbmmddgjldpifcjap/dashboard.html — and open developer tools.

BraveDebug00287
(View large version88)

For the layout, you have a bit of help using Shift + F8, which will let you inspect the complete frame of Brave. And you’ll discover that Brave is an Electron app using React!

Note, for instance, the data-reactroot attribute.

BraveDebug00389
(View large version90)

Note: I had to slightly modify the CSS of the extension for Brave because it currently displays popups with a transparent background by default, and I also had some issues with the height of my images collection. I’ve limited it to four elements in Brave.

Mozilla Firefox Link

Mozilla has really great documentation on debugging web extensions91.

For the client script part, it’s the same as in Edge, Chrome, Opera and Brave. Simply open the developer tools in the tab you’d like to debug, and you’ll find a moz-extension://guid section with your code to debug:

DebugInFirefox00192
(View large version93)

If you need to debug a tab that your extension would create (like Vorlon.js’ Page Analyzer extension), simply use the developer tools:

DebugInFirefox00294
(View large version95)

Finally, debugging a popup is a bit more complex but is well explained in the “Debugging Popups96” section of the documentation.

DebugInFirefox00397
(View large version98)

Publishing Your Extension In Each Store Link

Each vendor has detailed documentation on the process to follow to publish your extension in its store. They all take similar approaches. You need to package the extension in a particular file format — most of the time, a ZIP-like container. Then, you have to submit it in a dedicated portal, choose a pricing model and wait for the review process to complete. If accepted, your extension will be downloadable in the browser itself by any user who visits the extensions store.

Here are the various processes:

Please note that submitting a Microsoft Edge extension to the Windows Store is currently a restricted capability. Reach out to the Microsoft Edge team103 with your request to be a part of the Windows Store, and they’ll consider you for a future update.

I’ve tried to share as much of what I’ve learned from working on our Vorlon.js Page Analyzer extension104 and this little proof of concept.

Some developers remember the pain of working through various implementations to build their extension — whether it meant using different build directories, or working with slightly different extension APIs, or following totally different approaches, such as Firefox’s XUL extensions or Internet Explorer’s BHOs and ActiveX.

It’s awesome to see that, today, using our regular JavaScript, CSS and HTML skills, we can build great extensions using the very same code base and across all browsers!

Feel free to ping me on Twitter105 for any feedback.

(ms, vf, rb, yk, al, il)

Footnotes Link

  1. 1 https://browserext.github.io/
  2. 2 https://developer.apple.com/reference/safariextensions
  3. 3 https://www.smashingmagazine.com/2014/11/creating-save-later-chrome-extension-modern-web-tools/
  4. 4 https://www.smashingmagazine.com/2016/10/whats-the-deal-with-the-samsung-internet-browser/
  5. 5 https://www.smashingmagazine.com/2015/05/form-inputs-browser-support-issue/
  6. 6 https://www.smashingmagazine.com/2015/09/chrome-firefox-safari-opera-edge-impressive-web-browser-alternatives/
  7. 7 https://developer.chrome.com/extensions
  8. 8 https://developer.microsoft.com/en-us/microsoft-edge/platform/documentation/extensions/
  9. 9 https://channel9.msdn.com/Events/WebPlatformSummit/edgesummit2016/ES1614?wt.mc_id=DX_879946&OC.ID=DX_879946&CR_CC=DX_879946
  10. 10 https://developer.mozilla.org/en-US/Add-ons/WebExtensions
  11. 11 https://wiki.mozilla.org/WebExtensions
  12. 12 https://dev.opera.com/extensions/getting-started/
  13. 13 https://github.com/brave/browser-laptop/wiki/Developer-Notes-on-Installing-or-Updating-Extensions
  14. 14 https://www.davrous.com/2015/08/27/creating-an-accessible-breakout-game-using-web-audio-svg/
  15. 15 https://twitter.com/codepo8
  16. 16 https://www.youtube.com/watch?v=TWVNTsdm27U
  17. 17 https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html#tts-section
  18. 18 https://www.microsoft.com/cognitive-services/en-us/computer-vision-api
  19. 19 https://www.microsoft.com/cognitive-services/en-us/subscriptions?productId=/products/54d873dd5eefd00dc474a0f4
  20. 20 https://www.captionbot.ai/
  21. 21 https://www.smashingmagazine.com/wp-content/uploads/2016/12/CaptionBot-1-preview-opt.png
  22. 22 https://www.microsoft.com/cognitive-services/en-us/speech-api
  23. 23 https://www.microsoft.com/cognitive-services/en-us/subscriptions?productId=/products/Bing.Speech.Preview
  24. 24 https://github.com/davrous/BingTTSClientJSLib
  25. 25 https://visual-recognition-demo.mybluemix.net/
  26. 26 https://cloud.google.com/vision/
  27. 27 http://github.com/davrous/dareangel
  28. 28 https://developer.microsoft.com/en-us/microsoft-edge/platform/documentation/extensions/api-support/
  29. 29 https://developer.mozilla.org/en-US/Add-ons/WebExtensions
  30. 30 https://dev.opera.com/extensions/apis/
  31. 31 https://github.com/davrous/dareangel/blob/master/manifest.json
  32. 32 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Slide1-large-opt.png
  33. 33 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Slide1-large-opt.png
  34. 34 https://github.com/davrous/dareangel/blob/master/manifest.json
  35. 35 https://developer.chrome.com/extensions/manifest
  36. 36 https://developer.microsoft.com/en-us/microsoft-edge/platform/documentation/extensions/api-support/supported-manifest-keys/
  37. 37 https://developer.mozilla.org/en-US/Add-ons/WebExtensions/manifest.json
  38. 38 https://dev.opera.com/extensions/architecture-overview/#the-content-script
  39. 39 https://dev.opera.com/extensions/content-scripts/
  40. 40 https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Content_scripts
  41. 41 https://developer.chrome.com/extensions/content_scripts
  42. 42 https://github.com/davrous/dareangel/blob/master/dareangel.client.ts
  43. 43 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Slide2-large-opt.png
  44. 44 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Slide2-large-opt.png
  45. 45 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Slide3-large-opt.png
  46. 46 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Slide3-large-opt.png
  47. 47 https://github.com/davrous/dareangel/blob/master/dashboard.html
  48. 48 https://github.com/davrous/dareangel/blob/master/dashboard.css
  49. 49 https://github.com/davrous/dareangel/blob/master/dareangel.dashboard.js
  50. 50 https://www.microsoft.com/cognitive-services/en-us/Computer-Vision-API/documentation/AnalyzeImage
  51. 51 https://dev.projectoxford.ai/docs/services/56f91f2d778daf23d8ec6739/operations/56f91f2e778daf14a499e1fa
  52. 52 https://www.smashingmagazine.com/wp-content/uploads/2016/12/xSlide4_thumb-large-opt.png
  53. 53 https://www.smashingmagazine.com/wp-content/uploads/2016/12/xSlide4_thumb-large-opt.png
  54. 54 https://github.com/davrous/dareangel
  55. 55 https://www.smashingmagazine.com/wp-content/uploads/2016/12/EnableInEdge001-1-preview-opt.png
  56. 56 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Edge001-preview-opt.png
  57. 57 https://www.smashingmagazine.com/wp-content/uploads/2016/12/EnableInEdge003-1-preview-opt.png
  58. 58 http://www.babylonjs.com/
  59. 59 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Chrome001-large-opt.png
  60. 60 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Chrome001-large-opt.png
  61. 61 http://www.babylonjs.com/
  62. 62 http://www.babylonjs.com/
  63. 63 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Firefox001-large-opt.png
  64. 64 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Firefox001-large-opt.png
  65. 65 https://developer.mozilla.org/en-US/Add-ons/Extension_Packaging
  66. 66 https://blog.brave.com/loading-chrome-extensions-in-brave/
  67. 67 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Brave001-large-opt.png
  68. 68 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Brave001-large-opt.png
  69. 69 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Brave002-large-opt.png
  70. 70 https://www.smashingmagazine.com/wp-content/uploads/2016/12/Brave002-large-opt.png
  71. 71 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInEdge001-large-opt.png
  72. 72 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInEdge001-large-opt.png
  73. 73 https://www.microsoft.com/store/p/page-analyzer/9nblggh4qws7
  74. 74 http://www.vorlonjs.io/
  75. 75 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInEdge002-large-opt.png
  76. 76 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInEdge002-large-opt.png
  77. 77 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInEdge003-preview-opt.png
  78. 78 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInEdge004-large-opt.png
  79. 79 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInEdge004-large-opt.png
  80. 80 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInChrome001-large-opt.png
  81. 81 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInChrome001-large-opt.png
  82. 82 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInChrome002-large-opt.png
  83. 83 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInChrome002-large-opt.png
  84. 84 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInChrome003-1-large-opt.jpg
  85. 85 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInChrome003-1-large-opt.jpg
  86. 86 https://www.smashingmagazine.com/wp-content/uploads/2016/12/BraveDebug001-preview-opt.png
  87. 87 https://www.smashingmagazine.com/wp-content/uploads/2016/12/BraveDebug002-large-opt.png
  88. 88 https://www.smashingmagazine.com/wp-content/uploads/2016/12/BraveDebug002-large-opt.png
  89. 89 https://www.smashingmagazine.com/wp-content/uploads/2016/12/BraveDebug003-large-opt.jpg
  90. 90 https://www.smashingmagazine.com/wp-content/uploads/2016/12/BraveDebug003-large-opt.jpg
  91. 91 https://developer.mozilla.org/fr/Add-ons/WebExtensions/Debugging
  92. 92 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInFirefox001-large-opt.png
  93. 93 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInFirefox001-large-opt.png
  94. 94 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInFirefox002-large-opt.png
  95. 95 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInFirefox002-large-opt.png
  96. 96 https://developer.mozilla.org/fr/Add-ons/WebExtensions/Debugging
  97. 97 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInFirefox003-large-opt.jpg
  98. 98 https://www.smashingmagazine.com/wp-content/uploads/2016/12/DebugInFirefox003-large-opt.jpg
  99. 99 https://developer.chrome.com/webstore/publish
  100. 100 https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Publishing_your_WebExtension
  101. 101 https://dev.opera.com/extensions/publishing-guidelines/
  102. 102 https://docs.microsoft.com/en-us/microsoft-edge/extensions/guides/packaging
  103. 103 http://aka.ms/extension-request
  104. 104 https://www.microsoft.com/store/p/page-analyzer/9nblggh4qws7
  105. 105 https://twitter.com/davrous

↑ Back to topTweet itShare on Facebook