countrylayer – The Must-Have API for Any Website

Original Source: http://feedproxy.google.com/~r/1stwebdesigner/~3/PSlPUZl9wug/

If you have ever worked on a project that deals with geographic information of any type – which, let’s face it, most websites and applications do these days – then you have likely had to come up with a solution for providing or accessing information about one if not more countries. Whether it’s population, location, currencies, languages, or any other information about a country you need, it can be challenging to find a way to dynamically bring those details into your project.

There are tools available to help you solve this problem, but all too often there are obstacles such as programming language, ease of use, complexity of integration, pricing, and other hurdles that you may encounter.

Until now.

countrylayer is a JSON API that is compatible with all programming languages, provides extensive and accurate data from almost 200 different countries, is simple and easy to integrate, and is affordable to use – starting at free!

In this article, we’re taking a look at what countrylayer has to offer and how you can start using it in your projects.

What Is countrylayer?

countrylayer is a service brought to you by apilayer that provides common information about countries via a REST API. With this API, users will be able to get detailed information about countries in the world. Because they can filter by name of a country, language, code, currency, the capital city, calling code, region, or regional bloc.

Using your project’s API key, you can access country data that is returned in a standard JSON format, which can then be easily parsed in any programming language.

Here is an example of an API response. Check out all of the information it provides:

[
{
"name": "Germany",
"topLevelDomain": [
".de"
],
"alpha2Code": "DE",
"alpha3Code": "DEU",
"callingCodes": [
"49"
],
"capital": "Berlin",
"altSpellings": [
"DE",
"Federal Republic of Germany",
"Bundesrepublik Deutschland"
],
"region": "Europe",
"subregion": "Western Europe",
"population": 81770900,
"latlng": [
51,
9
],
"demonym": "German",
"area": 357114,
"gini": 28.3,
"timezones": [
"UTC+01:00"
],
"borders": [
"AUT",
"BEL",
"CZE",
"DNK",
"FRA",
"LUX",
"NLD",
"POL",
"CHE"
],
"nativeName": "Deutschland",
"numericCode": "276",
"currencies": [
{
"code": "EUR",
"name": "Euro",
"symbol": "€"
}
],
"languages": [
{
"iso639_1": "de",
"iso639_2": "deu",
"name": "German",
"nativeName": "Deutsch"
}
],
"translations": {
"br": "Alemanha",
"de": "Deutschland",
"es": "Alemania",
"fa": "آلمان",
"fr": "Allemagne",
"hr": "Njemačka",
"it": "Germania",
"ja": "ドイツ",
"nl": "Duitsland",
"pt": "Alemanha"
},
"flag": "https://restcountries.eu/data/deu.svg",
"regionalBlocs": [
{
"acronym": "EU",
"name": "European Union"
}
],
"cioc": "GER"
},
{…}
]

Available API Endpoints

The countrylayer API comes with a number of endpoints, each providing different functionality. You can customize the request output data to get only the fields you need. This causes the request to execute faster, and reduces the response size.

Endpoint for all countries

GET https://api.countrylayer.com/v2/all
? access_key = API_KEY

Endpoint for country search by name

GET https://api.countrylayer.com/v2/name/{name}
? access_key = API_KEY & FullText=

Endpoint for country search by capital

GET https://api.countrylayer.com/v2/capital/{capital}
? access_key = API_KEY

Endpoint for country search by language

GET https://api.countrylayer.com/v2/language/{language}
? access_key = API_KEY

Endpoint for country search by currency

GET https://api.countrylayer.com/v2/currency/{currency}
? access_key = API_KEY

Endpoint for country search by region

GET https://api.countrylayer.com/v2/region/{region}
? access_key = API_KEY

Endpoint for country search by region block

GET https://api.countrylayer.com/v2/regionalbloc/{regionalbloc}
? access_key = API_KEY

Endpoint for country search by calling code

GET https://api.countrylayer.com/v2/callingcode/{callingcode}
? access_key = API_KEY

Endpoint for country search by alpha code

GET https://api.countrylayer.com/v2/alpha/{code}
? access_key = API_KEY

As you can see, these endpoints can be very useful for you to be able to access and utilize the country information needed for your project in a variety of manners, and helps to streamline and speed up your requests for the fastest execution possible.

You can learn more about how to integrate the countrylayer API into your projects by reading their extensive (yet surprisingly succinct and simple) documentation.

How Much Does Using The countrylayer API Cost?

You can get started for free with 100 searches per month and a rate limit of 1 per second. From there, pricing goes up from $9.99 per month for up to 5,000 searches, all the way to $149.99 per month for 250,000 searches. Enterprise pricing is also available on request. It’s important to note that SSL encryption is only available with paid subscription plans.

How Will You Use The countrylayer API In Your Projects?

As you can see, countrylayer is a relatively simple yet robust solution that can be used in a multitude of ways in your current and future projects. It is easy to integrate, provides accurate and extensive data, and is very affordable. We encourage you to give it a try – especially since you can get started for free! When you do, be sure to let us know what you think by reaching out on any of our social channels.


UEFA reveal vibrant new logo for 2024 Euros, and it comes with an easter egg

Original Source: http://feedproxy.google.com/~r/CreativeBloq/~3/WwXtzJFEwMo/euro-2024-logo

Will it be coming home?

60 High Quality Free Photoshop Patterns and Textures

Original Source: http://feedproxy.google.com/~r/Designrfix/~3/x3ykN6lFQ04/free-photoshop-patterns

Welcome to day 6 of freebie week on Designrfix. Today we have assembled a stunning collection of high quality free Photoshop patterns and textures. So if you are in search of some really cool patterns and textures for your latest project, this post is not to be missed. Feel free to download and use them…

The post 60 High Quality Free Photoshop Patterns and Textures appeared first on .

Building A Static-First MadLib Generator With Portable Text And Netlify On-Demand Builder Functions

Original Source: https://smashingmagazine.com/2021/10/static-first-madlib-generator-portable-text-netlify-builder-functions/

Creating an interactive experience with fiction can be a chore with traditional content management tools. Writing the prose, creating the forms, combining them in the frontend — these are often the domain of three different people.

Let’s make it the domain of just one content creator in which the user will fill out a form before reading the story — creating odd and often funny stories. This type of experience was popularized as “Madlibs.”

Generate your own madlibs in the demo;
Look through the final code on Github;
Get a fully-built version set up in your accounts.

How The Generator Will Work

An editor can create a series of madlibs that an end-user can fill out and save a copy with their unique answers. The editor will be working with the Sanity Studio inside a rich-text field that we’ll craft to provide additional information for our front-end to build out forms.

For the editor, it will feel like writing standard paragraph content. They’ll be able to write like they’re used to writing. They can then create specific blocks inside their content that will specify a part of speech and display text.

The front-end of the application can then use that data to both display the text and build a form. We’ll use 11ty to create the frontend with some small templates. The form that is built will display to the user before they see the text. They’ll know what type of speech and general context for the phrases and words they can enter.

After the form is submitted, they’ll be given their fully formed story (with hopefully hilarious results). This creation will only be set within their browser. If they wish to share it, they can then click the “Save” button. This will submit the entire text to a serverless function in Netlify to save it to the Sanity data store. Once that has been created, a link will appear for the user to view the permanent version of their madlib and share it with friends.

Since 11ty is a static site generator, we can’t count on a site rebuild to generate each user’s saved Madlib on the fly. We can use 11ty’s new Serverless mode to build them on request using Netlify’s On-Demand Builders to cache each Madlib.

The Tools
Sanity.io

Sanity.io is a unified content platform that believes that content is data and data can be used as content. Sanity pairs a real-time data store with three open-source tools: a powerful query language (GROQ), a CMS (Sanity Studio), and a rich-text data specification (Portable Text).

Portable Text

Portable Text is an open-source specification designed to treat rich text as data. We’ll be using Portable Text for the rich text that our editors will enter into a Sanity Studio. Data will decorate the rich text in a way that we can create a form on the fly based on the content.

11ty And 11ty Serverless

11ty is a static site generator built in Node. It allows developers to ingest data from multiple sources, write templates in multiple templating engines, and output simple, clean HTML.

In the upcoming 1.0 release, 11ty is introducing the concept of 11ty Serverless. This update allows sites to use the same templates and data to render pages via a serverless function or on-demand builder. 11ty Serverless begins to blur the line between “static site generator” and server-rendered page.

Netlify On-Demand Builders

Netlify has had serverless functions as part of its platform for years. For example, an “On-Demand Builder” is a serverless function dedicated to serving a cached file. Each builder works similarly to a standard serverless function on the first call. Netlify then caches that page on its edge CDN for each additional call.

Building The Editing Interface And Datastore

Before we can dive into serverless functions and the frontend, it would be helpful to have our data set up and ready to query.

To do this, we’ll set up a new project and install Sanity’s Studio (an open-source content platform for managing data in your Sanity Content Lake).

To create a new project, we can use Sanity’s CLI tools.

First, we need to create a new project directory to house both the front-end and the studio. I’ve called mine madlibs.

From inside this directory in the command line, run the following commands:

npm i -g @sanity/cli
sanity init

The sanity init command will run you through a series of questions. Name your project madlibs, create a new dataset called production, set the “output path” to studio, and for “project template,” select “Clean project with no predefined schemas.”

The CLI creates a new Sanity project and installs all the needed dependencies for a new studio. Inside the newly created studio directory, we have everything we need to make our editing experience.

Before we create the first interface, run sanity start in the studio directory to run the studio.

Creating The madlib Schema

A set of schema defines the studio’s editing interface. To create a new interface, we’ll create a new schema in the schema folder.

// madlibs/studio/schemas/madlib.js

export default {
// Name in the data
name: ‘madlib’,
// Title visible to editors
title: ‘Madlib Template’,
// Type of schema (at this stage either document or object)
type: ‘document’,
// An array of fields
fields: [
{
name: ‘title’,
title: ‘Title’,
type: ‘string’
},
{
title: ‘Slug’,
name: ‘slug’,
type: ‘slug’,
options: {
source: ‘title’,
maxLength: 200, // // will be ignored if slugify is set
}
},
]
}

The schema file is a JavaScript file that exports an object. This object defines the data’s name, title, type, and any fields the document will have.

In this case, we’ll start with a title string and a slug that can be generated from the title field. Once the file and initial code are created, we need to add this schema to our schema.js file.

// /madlibs/studio/schema/schema.js

// First, we must import the schema creator
import createSchema from ‘part:@sanity/base/schema-creator’

// Then import schema types from any plugins that might expose them
import schemaTypes from ‘all:part:@sanity/base/schema-type’

// Imports our new schema
import madlib from ‘./madlib’

// Then we give our schema to the builder and provide the result to Sanity
export default createSchema({
// We name our schema
name: ‘default’,
// Then proceed to concatenate our document type
// to the ones provided by any plugins that are installed
types: schemaTypes.concat([
// document
// adds the schema to the list the studio will display
madlib,
])
})

Next, we need to create a rich text editor for our madlib authors to write the templates. Sanity has a built-in way of handling rich text that can convert to the flexible Portable Text data structure.

To create the editor, we use an array field that contains a special schema type: block.

The block type will return all the default options for rich text. We can also extend this type to create specialty blocks for our editors.

export default {
// Name in the data
name: ‘madlib’,
// Title visible to editors
title: ‘Madlib Template’,
// Type of schema (at this stage either document or object)
type: ‘document’,
// An array of fields
fields: [
{
name: ‘title’,
title: ‘Title’,
type: ‘string’
},
{
title: ‘Slug’,
name: ‘slug’,
type: ‘slug’,
options: {
source: ‘title’,
maxLength: 200, // // will be ignored if slugify is set
}
},
{
title: ‘Madlib Text’,
name: ‘text’,
type: ‘array’,
of: [
{
type: ‘block’,
name: ‘block’,
of: [
// A new type of field that we’ll create next
{ type: ‘madlibField’ }
]
},
]
},
]
}

This code will set up the Portable Text editor. It builds various types of “blocks.” Blocks roughly equate to top-level data in the JSON data that Portable Text will return. By default, standard blocks take the shape of things like paragraphs, headers, lists, etc.

Custom blocks can be created for things like images, videos, and other data. For our madlib fields, we want to make “inline” blocks — blocks that flow within one of these larger blocks. To do that, the block type can accept its own of array. These fields can be any type, but we’ll make a custom type and add it to our schema in our case.

Creating A Custom Schema Type For The Madlib Field

To create a new custom type, we need to create a new file and import the schema into schema.js as we did for a new document type.

Instead of creating a schema with a type of document, we need to create one of type: object.

This custom type needs to have two fields: the display text and the grammar type. By structuring the data this way, we open up future possibilities for inspecting our content.

Alongside the data fields for this type, we can also specify a custom preview to show more than one field displayed in the rich text. To make this work, we define a React component that will accept the data from the fields and display the text the way we want it.

// /madlibs/studio/schemas/object/madLibField.js
import React from ‘react’

// A React Component that takes hte value of data
// and returns a simple preview of the data that can be used
// in the rich text editor
function madlibPreview({ value }) {
const { text, grammar } = value

return (

{text} ({grammar})

);
}

export default {
title: ‘Madlib Field Details’,
name: ‘madlibField’,
type: ‘object’,
fields: [
{
name: ‘displayText’,
title: ‘Display Text’,
type: ‘string’
},
{
name: ‘grammar’,
title: ‘Grammar Type’,
type: ‘string’
}
],
// Defines a preview for the data in the Rich Text editor
preview: {
select: {
// Selects data to pass to our component
text: ‘displayText’,
grammar: ‘grammar’
},

// Tells the field which preview to use
component: madlibPreview,
},
}

Once that’s created, we can add it to our schemas array and use it as a type in our Portable Text blocks.

// /madlibs/studio/schemas/schema.js
// First, we must import the schema creator
import createSchema from ‘part:@sanity/base/schema-creator’

// Then import schema types from any plugins that might expose them
import schemaTypes from ‘all:part:@sanity/base/schema-type’

import madlib from ‘./madlib’
// Import the new object
import madlibField from ‘./objects/madlibField’

// Then we give our schema to the builder and provide the result to Sanity
export default createSchema({
// We name our schema
name: ‘default’,
// Then proceed to concatenate our document type
// to the ones provided by any plugins that are installed
types: schemaTypes.concat([
// documents
madlib,
//objects
madlibField
])
})

Creating The Schema For User-generated Madlibs

Since the user-generated madlibs will be submitted from our frontend, we don’t technically need a schema for them. However, if we create a schema, we get an easy way to see all the entries (and delete them if necessary).

We want the structure for these documents to be the same as our madlib templates. The main differences in this schema from our madlib schema are the name, title, and, optionally, making the fields read-only.

// /madlibs/studio/schema/userLib.js
export default {
name: ‘userLib’,
title: ‘User Generated Madlibs’,
type: ‘document’,
fields: [
{
name: ‘title’,
title: ‘Title’,
type: ‘string’,
readOnly: true
},
{
title: ‘Slug’,
name: ‘slug’,
type: ‘slug’,
readOnly: true,
options: {
source: ‘title’,
maxLength: 200, // // will be ignored if slugify is set
},
},
{
title: ‘Madlib Text’,
name: ‘text’,
type: ‘array’,
readOnly: true,
of: [
{
type: ‘block’,
name: ‘block’,
of: [
{ type: ‘madlibField’ }
]
},
]
},
]
}

With that, we can add it to our schema.js file, and our admin is complete. Before we move on, be sure to add at least one madlib template. I found the first paragraph of Moby Dick worked surprisingly well for some humorous results.

Building The Frontend With 11ty

To create the frontend, we’ll use 11ty. 11ty is a static site generator written in and extended by Node. It does the job of creating HTML from multiple sources of data well, and with some new features, we can extend that to server-rendered pages and build-rendered pages.

Setting Up 11ty

First, we’ll need to get things set up.

Inside the main madlibs directory, let’s create a new site directory. This directory will house our 11ty site.

Open a new terminal and change the directory into the site directory. From there, we need to install a few dependencies.

// Create a new package.json
npm init -y
// Install 11ty and Sanity utilities
npm install @11ty/eleventy@beta @sanity/block-content-to-html @sanity/client

Once these have been installed, we’ll add a couple of scripts to our package.json

// /madlibs/site/package.json

“scripts”: {
“start”: “eleventy –serve”,
“build”: “eleventy”
},

Now that we have a build and start script, let’s add a base template for our pages to use and an index page.

By default, 11ty will look in an _includes directory for our templates, so create that directory and add a base.njk file to it.

<!DOCTYPE html>
<html lang=”en”>

<head>
<meta charset=”UTF-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<title>Madlibs</title>
{# Basic reset #}
<link rel=”stylesheet” href=”https://unpkg.com/some-nice-basic-css/global.css” />

</head>

<body>
<nav class=”container navigation”>
<a class=”logo” href=”/”>Madlibs</a>
</nav>

<div class=”stack container bordered”>
{# Inserts content from a page file and renders it as html #}
{{ content | safe }}
</div>

{% block scripts %}
{# Block to insert scripts from child templates #}
{% endblock %}
</body>

</html>

Once we have a template, we can create a page. First, in the root of the site directory, add an index.html file. Next, we’ll use frontmatter to add a little data — a title and the layout file to use.


title: Madlibs
layout: ‘base.njk’

<p>Some madlibs to take your mind off things. They’re stored in <a href=”https://sanity.io”>Sanity.io</a>, built with <a href=”https://11ty.dev”>11ty</a>, and do interesting things with Netlify serverless functions.</p>

Now you can start 11ty by running npm start in the site directory.

Creating Pages From Sanity Data Using 11ty Pagination

Now, we want to create pages dynamically from data from Sanity. To do this, we’ll create a JavaScript Data file and a Pagination template.

Before we dive into those files, we need to create a couple of utilities for working with the Sanity data.

Inside the site directory, let’s create a utils directory.

The first utility we need is an initialized Sanity JS client. First, create a file named sanityClient.js in the new utils directory.

// /madlibs/site/utils/sanityClient.js’
const sanityClient = require(‘@sanity/client’)
module.exports = sanityClient({
// The project ID
projectId: ‘<YOUR-ID>’,
// The dataset we created
dataset: ‘production’,
// The API version we want to use
// Best practice is to set this to today’s date
apiVersion: ‘2021-06-07’,
// Use the CDN instead of fetching directly from the data store
useCdn: true
})

Since our rich text is stored as Portable Text JSON, we need a way to convert the data to HTML. We’ll create a utility to do this for us. First, create a file named portableTextUtils.js in the utils directory.

For Sanity and 11ty sites, we typically will want to convert the JSON to either Markdown or HTML. For this site, we’ll use HTML to have granular control over the output.

Earlier, we installed @sanity/block-content-to-html, which will help us serialize the data to HTML. The package will work on all basic types of Portable Text blocks and styles. However, we have a custom block type that needs a custom serializer.

// Initializes the package
const toHtml = require(‘@sanity/block-content-to-html’)
const h = toHtml.h;

const serializers = {
types: {
madlibField: ({ node }) => {
// Takes each node of type madlibField
// and returns an HTML span with an id, class, and text
return h(‘span’, node.displayText, { id: node._key, className: ’empty’ })
}
}
}

const prepText = (data) => {
// Takes the data from a specific Sanity document
// and creates a new htmlText property to contain the HTML
// This lets us keep the Portable Text data intact and still display HTML
return {
…data,
htmlText: toHtml({
blocks: data.text, // Portable Text data
serializers: serializers // The serializer to use
})
}
}

// We only need to export prepText for our functions
module.exports = { prepText }

The serializers object in this code has a types object. In this object, we create a specialized serializer for any type. The key in the object should match the type given in our data. In our case, this is madlibField. Each type will have a function that returns an element written using hyperscript functions.

In this case, we create a span with children of the displayText from the current data. Later we’ll need unique IDs based on the data’s _key, and we’ll need a class to style these. We provide those in an object as the third argument for the h() function. We’ll use this same serializer setup for both our madlib templates and the user-generated madlibs.

Now that we have our utilities, it’s time to create a JavaScript data file. First, create a _data in the site directory. In this file, we can add global data to our 11ty site. Next, create a madlibs.js file. This file is where our JavaScript will run to pull each madlib template. The data will be available to any of our templates and pages under the madlibs key.

// Get our utilities
const client = require(‘../utils/sanityClient’)
const {prepText} = require(‘../utils/portableTextUtils’)
// The GROQ query used to find specific documents and
// shape the output
const query = *[_type == “madlib”]{
title,
“slug”: slug.current,
text,
_id,
“formFields”: text[]{
children[_type == “madlibField”]{
displayText,
grammar,
_key
}
}.children[]
}

module.exports = async function() {
// Fetch data based on the query
const madlibs = await client.fetch(query);

// Prepare the Portable Text data
const preppedMadlib = madlibs.map(prepText)
// Return the full array
return preppedMadlib
}

To fetch the data, we need to get the utilities we just created. The Sanity client has a fetch() method to pass a GROQ query. We’ll map over the array of documents the query returns to prepare their Portable Text and then return that to 11ty’s data cascade.

The GROQ query in this code example is doing most of the work for us. We start by requesting all documents with a _type of madlib from our Sanity content lake. Then we specify which data we want to return. The data starts simply: we need the title, slug, rich text, and id from the document, but we also want to reformat the data into a set of form fields, as well.

To do that, we create a new property on the data being returned: formFields. This looks at the text data (a Portable Text array) and loops over it with the [] operator. We can then build a new project on this data like we’re doing with the entire document with the {} operator.

Each text object has a children array. We can loop through that, and if the item matches the filter inside the [], we can run another projection on that. In this case, we’re filtering all children that have a _type == “madlibField”. In other words, any inline block that has an item with the type we created. We need the displayText, grammar, and _key for each of these. This will return an array of text objects with the children matching our filter. We need to flatten this to be an array of children. To do this, we can add the .children[] after the projects. This will return a flat array with just the children elements we need.

This gives us all the documents in an array with just the data we need (including newly reformatted items).

To use them in our 11ty build, we need a template that will use Pagination.

In the root of the site, create a madlib.njk file. This file will generate each madlib page from the data.


layout: ‘base.njk’
pagination:
data: madlibs
alias: madlib
size: 1
permalink: “madlibs/{{ madlib.slug | slug }}/index.html”

In the front matter of this file, we specify some data 11ty can use to generate our pages:

layout
The template to use to render the page.
pagination
An object with pagination information.
pagination.data
The data key for pagination to read.
pagination.alias
A key to use in this file for ease.
pagination.size
The number of madlibs per page (in this case, 1 per page to create individual pages).
permalink
The URLs at which each of these should live (can be partially generated from data).

With that data in place, we can specify how to display each piece of data for an item in the array.


layout: ‘base.njk’
pagination:
data: madlibs
alias: madlib
size: 1
permalink: “madlibs/{{ madlib.slug | slug }}/index.html”

<h2>{{ madlib.title }}</h2>
<p><em>Instructions:</em> Fill out this form, submit it and get your story. It will hopfully make little-to-no sense. Afterward, you can save the madlib and send it to your friends.</p>
<div class=”madlibtext”>
<a href=”#” class=”saver”>Save it</a>
{{ madlib.htmlText | safe }}
</div>
<h2>Form</h2>
<form class=”madlibForm stack”>
{% for input in madlib.formFields %}
<label>
{{ input.displayText }} ({{ input.grammar }})
<input type=”text” class=”libInput” name={{input._key}}>
</label>
{% endfor %}
<button>Done</button>
</form>

We can properly format the title and HTML text. We can then use the formFields array to create a form that users can enter their unique answers.

There’s some additional markup for use in our JavaScript — a form button and a link to save the finalized madlib. The link and madlib text will be hidden (no peeking for our users!).

For every madlib template, you created in your studio, 11ty will build a unique page. The final URLs should look like this

http://localhost:8080/madlibs/the-slug-in-the-studio/

Making The Madlibs Interactive

With our madlibs generated, we need to make them interactive. We’ll sprinkle a little JavaScript and CSS to make them interactive. Before we can use CSS and JS, we need to tell 11ty to copy the static files to our built site.

Copying Static Assets To The Final Build

In the root of the site directory, create the following files and directories:

assets/css/style.css — for any additional styling,
assets/js/madlib.js — for the interactions,
.eleventy.js — the 11ty configuration file.

When these files are created, we need to tell 11ty to copy the assets to the final build. Those instructions live in the .eleventy.js configuration file.

module.exports = function(eleventyConfig) {
eleventyConfig.addPassthroughCopy(“assets/”);
}

This instructs 11ty to copy the entire assets directory to the final build.

The only necessary CSS to make the site work is a snippet to hide and show the madlib text. However, if you want the whole look and feel, you can find all the styles in this file.

.madlibtext {
display: none
}
.madlibtext.show {
display: block;
}

Filling In The Madlib With User Input And JavaScript

Any frontend framework will work with 11ty if you set up a build process. For this example, we’ll use plain JavaScript to keep things simple. The first task is to take the user data in the form and populate the generic madlib template that 11ty generated from our Sanity data.

// Attach the form handler
const form = document.querySelector(‘.madlibForm’)
form.addEventListener(‘submit’, completeLib);

function showText() {
// Find the madlib text in the document
const textDiv = document.querySelector(‘.madlibtext’)
// Toggle the class “show” to be present
textDiv.classList.toggle(‘show’)
}

// A function that takes the submit event
// From the event, it will get the contents of the inputs
// and write them to page and show the full text
function completeLib(event) {
// Don’t submit the form
event.preventDefault();
const { target } = event // The target is the form element

// Get all inputs from the form in array format
const inputs = Array.from(target.elements)

inputs.forEach(input => {
// The button is an input and we don’t want that in the final data
if (input.type != ‘text’) return
// Find a span by the input’s name
// These will both be the _key value
const replacedContent = document.getElementById(input.name)
// Replace the content of the span with the input’s value
replacedContent.innerHTML = input.value
})
// Show the completed madlib
showText();
}

This functionality comes in three parts: attaching an event listener, taking the form input, inserting it into the HTML, and then showing the text.

When the form is submitted, the code creates an array from the form’s inputs. Next, it finds elements on the page with ids that match the input’s name — both created from the _key values of each block. It then replaces the content of that element with the value from the data.

Once that’s done, we toggle the full madlib text to show on the page.

We need to add this script to the page. To do this, we create a new template for the madlibs to use. In the _includes directory, create a file named lib.njk. This template will extend the base template we created and insert the script at the bottom of the page’s body.

{% extends ‘base.njk’ %}

{% block scripts %}
<script>
var pt = {{ madlib.text | dump | safe }}
var data = {
libId: {{ madlib._id }},
libTitle: {{ madlib.title }}
}
</script>
<script src=”/assets/js/madlib.js”></script>
{% endblock %}

Then, our madlib.njk pagination template needs to use this new template for its layout.


layout: ‘lib.njk’
pagination:
data: madlibs
alias: madlib
size: 1
permalink: “madlibs/{{ madlib.slug | slug }}/index.html”

// page content

We now have a functioning madlib generator. To make this more robust, let’s allow users to save and share their completed madlibs.

Saving A User Madlib To Sanity With A Netlify Function

Now that we have a madlib displayed to the user, we need to create the link for saving send the information to Sanity.

To do that, we’ll add some more functionality to our front-end JavaScript. But, first, we need to add some more data pulled from Sanity into our JavaScript, so we’ll add a couple of new variables in the scripts block on the lib.njk template.

{% extends ‘base.njk’ %}

{% block scripts %}
<script>
// Portable Text data
var pt = {{ madlib.text | dump | safe }}
var data = {
libId: {{ madlib._id }},
libTitle: {{ madlib.title }}
}
</script>
<script src=”/assets/js/madlib.js”></script>
{% endblock %}

We can write a script to send it and the user-generated answers to a serverless function to send to Sanity with that additional data.

// /madlibs/site/assets/js/madlib.js

// … completeLib()

async function saveLib(event) {
event.preventDefault();

// Return an Map of ids and content to turn into an object
const blocks = Array.from(document.querySelectorAll(‘.empty’)).map(item => {
return [item.id, { content: item.outerText }]
})
// Creates Object ready for storage from blocks map
const userContentBlocks = Object.fromEntries(blocks);

// Formats the data for posting
const finalData = {
userContentBlocks,
pt, // From nunjucks on page
…data // From nunjucks on page
}

// Runs the post data function for createLib
postData(‘/.netlify/functions/createLib’, finalData)
.then(data => {
// When post is successful
// Create a div for the final link
const landingZone = document.createElement(‘div’)
// Give the link a class
landingZone.className = “libUrl”
// Add the div after the saving link
saver.after(landingZone)
// Add the new link inside the landing zone
landingZone.innerHTML = <a href=”/userlibs/${data._id}/” class=”savedUrl”>Your url is /userlibs/${data._id}/</a>

}).catch(error => {
// When errors happen, do something with them
console.log(error)
});
}

async function postData(url = ”, data = {}) {
// A wrapper function for standard JS fetch
const response = await fetch(url, {
method: ‘POST’,
mode: ‘cors’,
cache: ‘no-cache’,
credentials: ‘same-origin’,
headers: {
‘Content-Type’: ‘application/json’
},
body: JSON.stringify(data)
});
return response.json(); // parses JSON response into native JavaScript objects
}

We add a new event listener to the “Save” link in our HTML.

The saveLib function will take the data from the page and the user-generated data and combine them in an object to be handled by a new serverless function. The serverless function needs to take that data and create a new Sanity document. When creating the function, we want it to return the _id for the new document. We use that to create a unique link that we add to the page. This link will be where the newly generated page will be.

Setting Up Netlify Dev

To use Netlify Functions, we’ll need to get our project set up on Netlify. We want Netlify to build and serve from the site directory. To give Netlify this information, we need to create a netlify.toml file at the root of the entire project.

[build]
command = “npm run build” # Command to run
functions = “functions” # Directory we store the functions
publish = “_site” # Folder to publish (11ty automatically makes the _site folder
base = “site” # Folder that is the root of the build

To develop these locally, it’s helpful to install Netlify’s CLI globally.

npm install -g netlify-cli

Once that’s installed, you can run netlify dev in your project. This will take the place of running your start NPM script.

The CLI will run you through connecting your repository to Netlify. Once it’s done, we’re ready to develop our first function.

Creating A Function To Save Madlibs To Sanity

Since our TOML file sets the functions directory to functions, we need to create the directory. Inside the directory, make a createLib.js file. This will be the serverless function for creating a madlib in the Sanity data store.

The standard Sanity client we’ve been using is read-only. To give it write permissions, we need to reconfigure it to use an API read+write token. To generate a token, log into the project dashboard and go to the project settings for your madlibs project. In the settings, find the Tokens area and generate a new token with “Editor” permissions. When the token is generated, save the string to Netlify’s environment variables dashboard with the name SANITY_TOKEN. Netlify Dev will automatically pull these environment variables into the project while running.

To reconfigure the client, we’ll require the file from our utilities, and then run the .config() method. This will let us set any configuration value for this specific use. We’ll set the token to the new environment variable and set useCdn to false.

// Sanity JS Client
// The build client is read-only
// To use to write, we need to add an API token with proper permissions
const client = require(‘../utils/sanityClient’)
client.config({
token: process.env.SANITY_TOKEN,
useCdn: false
})

The basic structure for a Netlify function is to export a handler function that is passed an event and returns an object with a status code and string body.

// Grabs local env variables from .env file
// Not necessary if using Netlify Dev CLI
require(‘dotenv’).config()

// Sanity JS Client
// The build client is read-only
// To use to write, we need to add an API token with proper permissions
const client = require(‘../utils/sanityClient’)
client.config({
token: process.env.SANITY_TOKEN,
useCdn: false
})

// Small ID creation package
const { nanoid } = require(‘nanoid’)

exports.handler = async (event) => {
// Get data off the event body
const {
pt,
userContentBlocks,
id,
libTitle
} = JSON.parse(event.body)

// Create new Portable Text JSON
// from the old PT and the user submissions
const newBlocks = findAndReplace(pt, userContentBlocks)

// Create new Sanity document object
// The doc’s _id and slug are based on a unique ID from nanoid
const docId = nanoid()
const doc = {
_type: “userLib”,
_id: docId,
slug: { current: docId },
madlib: id,
title: ${libTitle} creation,
text: newBlocks,
}

// Submit the new document object to Sanity
// Return the response back to the browser
return client.create(doc).then((res) => {
// Log the success into our function log
console.log(Userlib was created, document ID is ${res._id})
// return with a 200 status and a stringified JSON object we get from the Sanity API
return { statusCode: 200, body: JSON.stringify(doc) };
}).catch(err => {
// If there’s an error, log it
// and return a 500 error and a JSON string of the error
console.log(err)
return {
statusCode: 500, body: JSON.stringify(err)
}
})
}

// Function for modifying the Portable Text JSON
// pt is the original portable Text
// mods is an object of modifications to make
function findAndReplace(pt, mods) {
// For each block object, check to see if a mod is needed and return an object
const newPT = pt.map((block) => ({
…block, // Insert all current data
children: block.children.map(span => {
// For every item in children, see if there’s a modification on the mods object
// If there is, set modContent to the new content, if not, set it to the original text
const modContent = mods[span._key] ? mods[span._key].content : span.text
// Return an object with all the original data, and a new property
// displayText for use in the frontends
return {
…span,
displayText: modContent
}
})
}))
// Return the new Portable Text JSON
return newPT
}

The body is the data we just submitted. For ease, we’ll destructure the data off the event.body object. Then, we need to compare the original Portable Text and the user content we submitted and create the new Portable Text JSON that we can submit to Sanity.

To do that, we run a find and replace function. This function maps over the original Portable Text and for every child in the blocks, replace its content with the corresponding data from the modfications object. If there isn’t a modification, it will store the original text.

With modified Portable Text in hand, we can create a new object to store as a document in the Sanity content lake. Each document needs a unique identifier (which we can use the nanoid NPM package to create. We’ll also let this newly created ID be the slug for consistency.

The rest of the data is mapped to the proper key in our userLib schema we created in the studio and submitted with the authenticated client’s .create() method. When success or failure returns from Sanity, we pass that along to the frontend for handling.

Now, we have data being saved to our Sanity project. Go ahead and fill out a madlib and submit. You can view the creation in the studio. Those links that we’re generating don’t work yet, though. This is where 11ty Serverless comes in.

Setting Up 11ty Serverless

You may have noticed when we installed 11ty that we used a specific version. This is the beta of the upcoming 1.0 release. 11ty Serverless is one of the big new features in that release.

Installing The Serverless Plugin

11ty Serverless is an included plugin that can be initialized to create all the boilerplate for running 11ty in a serverless function. To get up and running, we need to add the plugin to our .eleventy.js configuration file.

const { EleventyServerlessBundlerPlugin } = require(“@11ty/eleventy”);

module.exports = function (eleventyConfig) {
eleventyConfig.addPassthroughCopy(“assets/”);

eleventyConfig.addPlugin(EleventyServerlessBundlerPlugin, {
name: “userlibs”, // the name to use for the functions
functionsDir: “./functions/”, // The functions directory
copy: [“utils/”], // Any files that need to be copied to make our scripts work
excludeDependencies: [“./_data/madlibs.js”] // Exclude any files you don’t want to run
});
};

After creating this file, restart 11ty by rerunning netlify dev. On the next run, 11ty will create a new directory in our functions directory named userlibs (matching the name in the serverless configuration) to house everything it needs to have to run in a serverless function. The index.js file in this directory is created if it doesn’t exist, but any changes you make will persist.

We need to make one small change to the end of this file. By default, 11ty Serverless will initialize using standard serverless functions. This will run the function on every load of the route. That’s an expensive load for content that can’t be changed after it’s been generated. Instead, we can change it to use Netlify’s On-Demand Builders. This will build the page on the first request and cache the result for any later requests. This cache will persist until the next build of the site.

To update the function, open the index.js file and change the ending of the file.

// Comment this line out
exports.handler = handler

// Uncomment these lines
const { builder } = require(“@netlify/functions”);
exports.handler = builder(handler);

Since this file is using Netlify’s functions package, we also need to install that package.

npm install @netlify/functions

Creating A Data File For User-generated Madlibs

Now that we have an On-Demand Builder, we need to pull the data for user-generated madlibs. We can create a new JavaScript data file in the _data file named userlibs.js. Like our madlibs data file, the file name will be the key to get this data in our templates.

// /madlibs/site/_data/userlibs.js

const client = require(‘../utils/sanityClient’)
const {prepText} = require(‘../utils/portableTextUtils’)

const query = *[_type == “userLib”]{
title,
“slug”: slug.current,
text,
_id
}

module.exports = async function() {
const madlibs = await client.fetch(query);
// Protect against no madlibs returning
if (madlibs.length == 0) return {“404”: {}}

// Run through our portable text serializer
const preppedMadlib = madlibs.map(prepText)

// Convert the array of documents into an object
// Each item in the Object will have a key of the item slug
// 11ty’s Pagination will create pages for each one
const mapLibs = preppedMadlib.map(item => ([item.slug, item]))
const objLibs = Object.fromEntries(mapLibs)
return objLibs
}

This data file is similar to what we wrote earlier, but instead of returning the array, we need to return an object. The object’s keys are what the serverless bundle will use to pull the correct madlib on request. In our case, we’ll make the item’s slug the key since the serverless route will be looking for a slug.

Creating A Pagination Template That Uses Serverless Routes

Now that the plugin is ready, we can create a new pagination template to use the generated function.

In the root of our site, add a userlibs.njk template. This template will be like the madlibs.njk template, but it will use different data without any interactivity.


layout: ‘base.njk’
pagination:
data: userLibs
alias: userlib
size: 1
serverless: eleventy.serverless.path.slug

permalink:
userlibs: “/userlibs/:slug/”

<h2>{{ userlib.title }}</h2>
<div>
{{ userlib.htmlText | safe }}
</div>

In this template, we use base.njk to avoid including the JavaScript. We specify the new userlibs data for pagination.

To pull the correct data, we need to specify what the lookup key will be. On the pagination object, we do this with the serverless property. When using serverless routes, we get access to a new object: eleventy.serverless. On this object, there’s a path object that contains information on what URL the user requested. In this case, we’ll have a slug property on that object. That needs to correspond to a key on our pagination data.

To get the slug on our path, we need to add it to the permalink object. 11ty Serverless allows for more than one route for a template. The route’s key needs to match the name provided in the .eleventy.js configuration. In this case, it should be userlibs. We specify the static /userlibs/ start to the path and then add a dynamic element: :slug/. This slug will be what gets passed to eleventy.serverless.path.slug.

Now, the link that we created earlier by submitting a madlib to Sanity will work.

Next Steps

Now we have a madlib generator that saves to a data store. We build only the necessary pages to allow a user to create a new madlib. When they create one, we make those pages on-demand with 11ty and Netlify Functions. From here, we can extend this further.

Statically build the user-generated content as well as render them on request.
Create a counter for the total number of madlibs saved by each madlib template.
Create a list of words users use by parts of speech.

When you can statically build AND dynamically render, what sorts of applications does this open up?

Best Changeable Letter Boards

Original Source: http://feedproxy.google.com/~r/Designrfix/~3/pzHV9qen-O4/best-changeable-letter-boards

Are you planning to purchase a changeable letter board, and then this review is for you. You can use the board to help your children learn much as they figure out things independently. Thanks to these boards, which can be used for home decoration or background for taking photos. You can use them to pass…

The post Best Changeable Letter Boards appeared first on designrfix.com.

How to create a style guide: 25 expert tips for designers

Original Source: http://feedproxy.google.com/~r/CreativeBloq/~3/8eFkGsEzfu4/create-style-guides-1012963

Learn how to create a style guide with these useful tips.

7 Tips for Transforming CX with Live Chat

Original Source: https://www.webdesignerdepot.com/2021/09/7-tips-for-transforming-cx-with-live-chat/

Not so long ago, customers only had a couple of ways to interact with brands. 

If you had an issue with a product or service, you could reach out through the customer service phone number or send an email. Occasionally, sites would introduce dedicated forms on their website that allowed consumers to send support tickets straight to the service desk – but that was it.

The problem with this kind of service was all the waiting. 

Send an email or ticket, and you have no idea when the company is going to get back to you. Customers end up refreshing their inbox all day, waiting for a response. Call the company, and 9 times out of 10, you’ll be placed on hold. You can’t exactly do much when you’re stuck listening to hold music, so customers are gradually getting more frustrated as they wait for a response. 

Fortunately, the evolving digital age has introduced a new solution: live chat.

Transforming Your CX With Live Chat

Live chat is a quick and convenient way for your customers to contact your business and get a response immediately. The result is happier clients, better customer satisfaction scores, and even opportunities for bigger sales. 

More than 41% of customers say they expect to see live chat on a site. 

Even if you don’t have an agent on hand to answer a chat message immediately, you can create an automated system that notifies your customer when someone is available. That means they can go and do other things while they’re waiting for a response. Live chat solutions with bots can even allow your customers to fix problems for themselves. That’s pretty convenient!

Widgets equipped with answers to commonly asked questions can automatically deal with customer queries or help them find solutions to their problems before passing them over to an agent. This means that your customer gets a solution faster, and your agents don’t have as much pressure to deal with. It’s a win-win – as long as you get it right. 

Unfortunately, a lot of companies don’t know how to implement live chat experiences correctly. 

Kayako’s study into 400 customers found that 47% couldn’t remember the last time they’d had a positive experience through a live chat tool.  

How to Upgrade Live Chat CX

The evidence shows that customers love the idea of live chat, but the reality of how businesses implement this technology isn’t always ideal. 

However, since 86% of customers say they’re willing to spend more on a better customer experience, it’s worth figuring out what separates a good live chat interaction from a bad one. 

1. Set Expectations Instantly

Setting the right expectations is crucial if you want to generate better satisfaction for your customers at a later date. When customers know what to expect from your live chat strategy, they can also make more informed decisions about which support channels they’re going to use, and whether they want to hang around for someone to answer their messages. 

The first thing you should do is showcase your agent’s availability. In this example from Help Scout, you can see whether the team is active, online, and ready to talk. The company also sets expectations for how quickly you can get an email response if you don’t want to chat.

Other ways to set expectations include:

Showing your opening hours: List when team members are usually available to answer questions if you’re not currently online. 
Topics: Offer your customers some topics that they can ask about or use the welcome message on your chat tool to direct your customers to an FAQ page. 
Restrictions: If there’s anything you can’t deal with over live chat, like changing a customer’s password, let them know in advance so they don’t waste time.

2. Leverage Pre-Chat Forms

Pre-chat forms are some of the most important parts of the live chat experience. They ask your customer to explain their issue to your chatbot so that they can be directed towards the right agent. Using these forms correctly ensures that your agent has all the information they need to solve a problem fast. 

You can even set up automated systems that direct customers to different agents and teams based on their needs. For instance, the live chat app on Outgrow.co gives customers the option to fill out different forms depending on whether they want answers to a question, a demo, or something else.

The button you click on dictates which professional you’ll get through to. Although filling out a form can seem like an extra friction point for your customer at first, it helps to streamline the customer journey. After all, if you can direct the customer to the right agent the first time, there are fewer chances that they’ll need to explain their issue to various different people. 

Here are a few things you can ask for in the live chat form to make it more effective:

The customer’s name: This will help to personalize the conversation. It could also be an opportunity to track down any background information you have about an existing customer and the orders that they may want to speak to you about.
An email address: Having an email address will allow you to bring up a customer’s record on your CRM. It also means that you can send any information that the customer needs to their email inbox at the end of the conversation.
A brief explanation: Ask your customers to share what they’re reaching out to you about and use keywords in their message to assign the chat to the right agent or professional. You could even add a drop-down menu of topics for them to choose from. 

Remember, don’t ask for too much information straight away, or you’ll risk your clients feeling that the service experience is too complicated. 

3. Make Sure It Works Everywhere

We’ve reached the point now where every customer expects a brand’s website to be responsive on any device. Most web-building templates automatically work on mobile tablets and smartphones. Additionally, it’s becoming increasingly easy for companies to transform their website and online store experiences into dedicated apps too. 

However, while most businesses know that their site needs to be responsive, they often forget about the mobile element when it comes to live chat. If your live chat function is only available on the web browser version of your website, then this is going to end up making your mobile customers pretty unhappy. They don’t want to have to stop browsing on their phone just to connect with you. 

Ideally, you’ll want to create a separate component for your mobile app where your customers can easily access the same live chat functions they’d have on your browser-based site.

If you’re just offering live chat through a mobile version of your website, make sure that it’s easy for your customer to click into the chat section and send messages without accidentally ending up on a different tab or page. It might also be worth setting up functions that allow your chat app to send push notifications to your customer’s phone whenever they get a new message. 

Being able to put their smartphone down or switch to another app while they wait for a response will provide a much more intuitive experience for your audience. 

4. Make Sure You Support All the Right Languages

You’d think that this CX tip for live chat would be obvious, but it’s shocking how many companies fail to offer support for all the languages that their customers might use. If you’re selling your products throughout the world, and you know you have customers in China, then it doesn’t make much sense to only offer live chat in English. 

Some of the available live chat apps on the market today come with features that allow you to automatically translate languages when your agents are talking to foreign customers. For instance, LiveChat currently supports 45 languages. 

If you’re creating your own chat app from scratch, then you’re going to need to work with your developer or designer to make sure that the right languages are supported. Remember, you don’t have to cover everything, but at least make sure that you can connect with the most common groups of customers in your CRM. 

Ensure that if you are using multiple languages, your customers know how to switch to their preferred option too. Usually, the best way to do this is with a drop-down menu. You could also use little flag icons of the countries that you support. 

5. Find Ways to Reduce First Response Time

Speed is probably one of the biggest advantages of live chat, and the main reason that customers like it so much. According to the CMO council, fast response time is the number one thing that a customer looks at when measuring satisfaction. 

While you might not be able to have someone on-hand to answer your customers 24/7, you can improve the way they perceive your load times in a variety of ways. For instance, start by making it clear when your people are online to talk to your customers. Setting expectations on when you’ll be available to immediately respond should help to avoid frustration.

Keep all chats in the same place for agents: Having a combined contact center solution on the back-end makes responding to queries much easier for your agents. If they can see all of your brand’s live chat, social, and email conversations in one place, they don’t have to waste time jumping between different platforms and tabs. 
Set routing queues: Use an automated system to send every message you get to the most appropriate agent available. You can intelligently route conversations based on the issues that your customers have or the things they want to discuss. It’s also worth ensuring that your system prioritizes routing conversations to the first agent available. 
Send notifications: Make sure that you set your live chat system up to send push notifications to agents when a new message is waiting. It’s also with notifying your customer when they have a response, just in case they’ve switched to another tab. 

The notifications you send to your agents could come with access to a customer’s CRM file, so that your agent can go into a conversation with the context they need. Agents that instantly get context on a conversation don’t have to waste as much time tracking down the right information. Giving your agents context also means that they don’t have to ask repetitive questions, which could annoy your customer. 

6. Make the Chat Experience On-Brand

Every company wants to give their customer a slick experience with live chat. The solution you build needs to be easy to use, and responsive across every device. However, it also needs to be something that your customer associates with your brand. 

Companies generally have a lot of options for how a live chat window can look. You can adjust the appearance to suit your brand by picking specific colors, tweaking button shapes, and even changing the available fonts. 

Working the visual elements of your brand into the design of the live chat experience is the best way to make your customers feel comfortable and confident that they’re dealing with your company. For instance, Hubspot uses matching colors, rounded edges on chat bubbles, and even a fun illustration to make their chat experience more “branded.”

Remember, when you’re creating a Live Chat experience that’s “on brand”, it’s also a good idea to think about things like voice and tone. Infusing live chat with the unique personality of your brand will make the experience more memorable. 

If you usually stick with informal language and use a lot of slang, then it makes sense to continue that in live chat – even when you’re sending automated messages. To make sure your brand identity really shines through:

Write scripts for your automated messages in your brand’s tone of voice
Write guidance scripts for employees that highlight your tone for agents
Provide training on brand tone of voice for your support team
Encourage support agents to connect with customers on a personal level
Remember to set guidelines on how to use things like gifs, slang, and emojis too!

7. Make a Checklist For Security and Tech Issues

One of the most significant things that will affect the experience your customer has with your live chat service, is technical and security issues. Choose the right developer or designer to help with your app, and the risk of problems dwindle. You can also address the issue of having to constantly maintain, check, and update your live chat experience by using a pre-existing solution, like Intercom.

No matter how you choose to approach live chat, these are the things you’ll need to check for most:

Page load times: Page load times are crucial for user experience and SEO, so you should be taking them seriously already. Check your web chat software isn’t dragging down the performance of your page or causing unnecessary problems.
Cross-channel conversations: If your website has various subdomains, make sure that moving through these in chat won’t mean you lose the session. Customers don’t want to have to repeat themselves!
Functionality with browsers: Your chat app needs to work just as well on every browser and operating system – including mobile devices. 
Data management: Under things like GDPR, you need to ensure that you’re controlling user information safely. Ensure you have a DPA in place, and make sure that your web channel doesn’t affect any PCI-DSS compliance systems you have in place. Your chat solution may need to automatically mask credit card information, for instance.

Time to Enhance Your Live Chat Strategy

Ultimately, whether you like it or not, your customers love live chat technology, and they’re not going to stop looking for it on your website. Today’s consumers expect you to serve their interests by delivering customer support on the channels that they choose. Unfortunately, most companies just aren’t living up to expectations.

Following the tips above could help you to transform the way that you interact with your clients and improve your chances of better satisfaction overall.

Source

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

The post 7 Tips for Transforming CX with Live Chat first appeared on Webdesigner Depot.

The 25 best Photoshop plugins

Original Source: http://feedproxy.google.com/~r/CreativeBloq/~3/IvZ9EI_2zn8/best-photoshop-plugins-912722

The most creative, useful and time-saving Photoshop plugins.

Getting Your `head` Straight: A New CSS Performance Diagnostics Snippet

Original Source: https://smashingmagazine.com/2021/09/css-head-tag/

There are plenty of ways to detect performance bottlenecks and audit CSS. We can look into common performance bottlenecks and the complexity of stylesheets, the way we load assets, and the order in which it happens.

One helpful way to spot common problems easily is to use some sort of a performance diagnostics CSS — a dedicated stylesheet that highlights potential problems and errors.

Today, during his talk at Webexpo Prague 2021, Harry Roberts, a web performance consultant and front-end engineer, introduced a little helper that helps him spot common performance bottlenecks easily. And that is mostly related to the order of how assets are loaded in the <head>.

As Harry says,

“I spend a lot of my time looking through clients’ <head> tags to ensure everything in there is in the best possible shape it can be. There are a lot of complex and often conflicting rules that constitute ‘good’ <head> tags, and cross-referencing everything can soon grow unwieldy, so to make my life easier, I developed ct.css — a quick and dirty way of seeing inside of your <head>.”

ct.css is a little diagnostic snippet, named after Computed Tomography (CT) scans, that exposes potential performance issues in your page’s <head> tags, and will disappear as soon as you’ve fixed them.

Harry has put all the insights he’s learned from his performance work to a perfect <head> order, and the tool exposes some of the issues that often result from a suboptimal arrangement of <head> tags.

With the bookmarklet in the browser’s toolbar, browse to a website of your choice, click or activate the bookmarklet, and the tool highlights useful pointers for you to double-check when working around performance bottlenecks. Just a little helper to make your work a bit easier, and find all those hidden issues faster.

If you just want to play with the snippet, you can get it at csswizardry.com/ct. Happy debugging, everyone!

How Web Development Tools Are Helping Users Keep Pace With Rapid Change

Original Source: https://smashingmagazine.com/2021/09/web-development-tools-users-keep-pace-rapid-change/

Several years ago, I wrote about website builders for a living. Yes, that’s a thing. Back then there seemed to be a gulf between drag-and-drop tools and full-blown web development. Today, it’s heartening to see the likes of Wix adding more code-heavy options to their repertoire.

Judging by Velo by Wix’s report, I’m not alone in feeling that way.

The Covid-19 pandemic has forced much of the world online. Billions of people have been working, dating, and doom scrolling on the web more than ever before. To meet this change, businesses have been beefing up their online offering. Demand for web developers and development tools is higher than ever.

The team at Velo by Wix — which offers a full-stack Rapid Web Development platform — wanted to examine what this mass digital migration means for the industry. What web development platforms are being used? Who are they being used by, and why?

To answer those questions, Velo has conducted a survey of 1,200 developers and the resulting Rapid Web Development Report is pretty fascinating. In the space between drag-and-drop website builders and from-the-ground-up development, there’s an awful lot of demand, and not always for the reasons you might expect.

What Are Rapid Web Development Platforms?

Before getting into the meat and potatoes of the report, we should be clear on how Velo defines Rapid Web Development (RWD). In the broadest sense, it means using builders or tools that streamline the development process.

We all recognize the spectrum these things sit on, even if we haven’t put a name to it. From no- and low-code platforms like Wix and Weebly to techier visual tools like, well, Velo by Wix, they’re what we use when we want or need to quickly build sites and web apps — without coding everything from scratch.

Convenience and accessibility have long been the selling points of Rapid Web Development platforms. They handle many of the foundational aspects of sites so developers (or business owners, bloggers or activists) can focus instead on the functionality of their project.

They provide ready-made or built-in solutions for many aspects of the site. These include:

Infrastructure
Databases
Content management
Design
Servers
Security and privacy
Deployment
Maintenance
Business solutions
Search engine optimization

In short, they take care of the foundations while still giving control. Each of the aspects listed above could be full-time jobs on their own (at Smashing Magazine we’ve published enough articles on them to know), so the value of assistive tools is undeniable.

Key Findings

Let’s cover the key points before getting into the nitty-gritty. The report uses data from 1,200 respondents, 60% of whom describe themselves as entrepreneurs or freelancers. Together with agencies, these make up the majority of RWD users.

Those surveyed typically use Rapid Web Development platforms to support and grow their businesses, with speed, flexibility, and cost-effectiveness being their main appeals — especially in the Covid-19 era. Convenience trumps technical capabilities. The real value of such tools is how they can facilitate the running of businesses.

The Times They Are A-Changin’

Such a sharp focus on business makes sense given what’s gone on in the last 18 months. To call the Covid-19 a time of upheaval would be an understatement. Even the ever-changing web has been shaken up.

Of those surveyed, 42% said the pandemic has been a time of large or extreme change. There has been something of mass migration to e-commerce, with businesses having to move online to meet the demand.

Few businesses can afford to take months building bespoke web presences. The streamlined, out-of-the-box convenience and scalability of Rapid Web Development platforms have always made commercial sites a natural fit. This bears out in the report, with more than 80% of respondents saying RWD tools helped their businesses during the pandemic.

No Time To Waste

When it comes to the whys, 61% of respondents said they use Rapid Web Development platforms because they “improve efficiency.” That and “productivity” were the two most popular choices.

Why Use Rapid Web Development Platforms?

You also get a sense of how varied the use cases really are. While 56% of respondents said they use one RWD platform, the other 44% use multiple. Different builders have always had different strengths (Squarespace for design, Shopify for online shops, and so on), but it’s still interesting to see so many people seek efficiency and yet still find themselves using multiple platforms.

E-Commerce Thrives

In keeping with the march online, 44% of respondents said they use Rapid Web Development platforms to build e-commerce sites. This was the most common answer by far. Cost-effectiveness was the deciding factor for 64% of that subset. When people want to sell online, they want to get set up quickly and affordably. Add hospitality and restaurants into the mix and you have a hefty portion of the Rapid Web Development user base.

What Markets Are RWDs Used For?

That said, it’s clearly not all about the money. The second most common usage of Rapid Web Development was blogging and media, closely followed by tech. Having an online presence is invaluable across countless sectors, and website builders remain a popular way of achieving that.

Buckling Frameworks

A particularly insightful part of the report examines how Rapid Web Development platforms fit within the wider frameworks ecosystem. Gone are the days where website builders are only used by those who can’t code. Their convenience and flexibility make them viable options for just about everyone.

The most used framework among those surveyed was React, with just under two-thirds saying they were familiar with it. Angular was second with 33.6% and Vue third with 30.9%. Technical know-how is solid.

Despite that familiarity, frameworks are mainly used because they’re familiar, not necessarily because they’re loved. Only 25% of respondents said they use the frameworks they use because they like the product. Not a number totally out of the blue, but pretty damning all the same.

The appeal of web development tools takes on another dimension with this in mind. When faced with a one-off project like, say, a portfolio website, why would someone use a framework they don’t even like? Maybe they’d rather rustle something up with a builder in half the time.

Cost A Major Factor

Not everyone has the resources to hire a development team out of the gate. It’s a major investment of not only money, but time, too. When all is said and done, offsetting that cost is the main appeal of Rapid Web Development platforms.

When asked why they use them, the top three reasons from respondents were:

Percentage
Reason

64%
“It’s more cost effective.”

61%
“Keeps pace with customer needs.”

46%
“Gives leg up on competition.”

That one-two of being affordable and up to date is far ahead of any other factors. Even if those issues aren’t quite removed, they’re much more manageable.

Meanwhile, openness was something users didn’t care much about when it came to RWD tools. There is a time and place for open-source code and total technical control, and it ain’t business websites in a pandemic.

Tools In The Toolbox

There is no one right way to do web development. The overarching sense one gets from the Rapid Web Development Report is that a greater variety of tools ensures we can each build websites and applications in ways that are right for us.

As the report itself summarises, users “aren’t committed to one specific technology, but to practicality.” Each platform is a tool in our web development toolbox. Sometimes only a React app from scratch will do. Other times, however, assistive technology is the only way to get the results you’re looking for, by the deadline you need to meet.

This has rung especially true during the pandemic, with countless businesses moving online and turning to Rapid Web Development tools to help them keep up with seemingly relentless change.

Would-be web developers sit on a spectrum all the way from total beginners to full-stack experts, and everything in between. It’s reassuring to see tools reflecting that reality and helping people get online.

Read the full Rapid Web Development report →