wit

Balancing Image Speed and Quality with imgix

Users expect a website to load fast. An average web page loads in about 2.5 seconds. The longer the user has to wait, the higher the user bounce rate. There are a lot of factors that go into site speed, but images account for about 75% of the page weight on an application or website. Google’s Core Web Vitals uses several metrics to rank sites. Visual site speed or largest contentful paint affects ROI as slower sites have fewer repeat users and fewer sales.

Without properly sized images, both site speed and image quality are affected. Accordingly, we use several methods to deliver properly sized images. Our primary solution is imgix because it is easy to implement and saves managers and clients time and effort. 

Imgix Key Features

Imgix provides a lot of features — some we consistently use on projects, and others we use in very specific situations. 

Responsive Images

Setting up responsive images can be complex. As the variety of devices and their screen resolutions continue to expand, managing all the different image requirements is increasingly challenging.

Consider this scenario: a website’s images look crisp and clear on a high-resolution monitor. When that same page is viewed on a mobile device, the images are so large the page takes forever to load. A solution could be to upload a smaller image for mobile, right? It's not quite that simple. We need eight or more different sizes of the same image to account for different screen sizes and retina screens. Keeping track of all the image sizes and saving each size gets complex and would be nearly impossible to do manually on a site that has hundreds or thousands of images. 

One of our clients, National Park Foundation (NPF), wanted to clarify its message to better target major donors. Their gorgeous, large scenic images are essential to their website strategy.  NPF needed the images throughout their site to be crisp and clear at all screen sizes. Using imgix, NPF content managers can load high-resolution images to the CMS and not worry about the site's speed or performance. They rely on imgix to deliver the correctly resized image for any user's screen.

Imgix does this with their Device Pixel Ratio and Client Hints which automatically sets the pixel density for the image based on the user's device. Those API parameters can be easily set in the URLs for the image’s `srcset`. This allows developers to set an image width for an image `srcset` and then imgix delivers the right pixel ratio image to the user. We use `srcset` with imgix on other client sites like Bezos Earth Fund and Human Rights Campaign as well.

Resize and Cropping

Imgix allows you to crop images in addition to setting an image’s focal point. So, only one image needs to be uploaded and it can be used at multiple sizes and croppings throughout the site. Let's say we upload a large landscape image, but on some pages we only need to use a portion of the image cropped as a square. Imgix will crop the image and deliver the smaller versions on the pages we need while persisting the larger versions on other pages.

At Viget we use resizing and cropping on our own website, including our articles, to crop the staff photo to a smaller size at the top of the articles. This makes it possible for us to upload the staff photo once and the article image gets created automatically. 

Color Palette 

Another feature that we've used on client sites is the Color Palette API which allows you as many colors as you want from an image. For example, the Shedd Aquarium website that we built uses this feature by pulling a vibrant color from the image and setting it as the background color for the page hero. Aside from taking the manual work out of closely aligning photography with a page’s design, there’s an additional benefit: if you are on a slow connection, you will see a dynamic colored banner at the top before the image loads.

Image Upscaling

Another valuable feature is the ability to upscale images. Even if you upload an image that is low resolution, it can still be used at a higher resolution. This is especially useful for e-commerce sites or applications where users are uploading their images.  The upscale feature uses Generative AI to take a pixelated image and create a higher-resolution image. The final image will not be perfect, but it looks more professional. See the upscale demo on imgix.

Non-upscaled image
Upscaled image using Imgix

PDF Preview Images

There is also a PDF page to image option in imgix. The API enables the generation of a page-specific image preview from the PDF, which can serve as both a thumbnail and a full-size preview. When we built AHIP.org, they had a resources section for their members containing quite a few PDFs. To help with clarity and findability, we used imgix to show previews of the PDF documents to non-members. This feature allows AHIP to upload resource PDFs without having to also upload any thumbnail images. 

Face Detection

Another nice feature is a face detection parameter that you can pass to the API. This allows you to upload a photo and no matter the cropping or size it will keep the face as the focal point of the image. We used this feature on NEA for their team member page. It's great for user profile images that are used in different contexts throughout the site. 

Video Streaming

Videos have become a key design element on websites. However, determining which service to use for embedding those videos is an ongoing topic of discussion. Video platforms enable you to integrate the video onto the page, yet they introduce scripts that may impede page loading speed. Imgix offers a video embed service that allows content managers to keep all the images and videos in one place. The videos are automatically encoded to Adaptive Bitrate Streaming to get the best compression and video quality. So, videos load fast and look great on mobile and desktop. 

Imgix Video API with Adaptive Bitrate Streaming

Performance 

A lot of CMSs have image transformations built in. An image transformation encompasses everything for that image including responsive sizes, cropping, resizing, and face detection from the original. This is great for small sets of images, but transformations quickly get out of hand the more images there are on a site. For example, the homepage of the National Park Foundation has a minimum of 96 image transformations. 

Processing all of those image transformations uses a lot of server resources. Imgix saves the images and delivers them through their CDN. The imgix image CDN has an average of 0.15 milliseconds return on requests which enables images to load as quickly as possible. The CDN also caches the images on CDN edge nodes making them immediately available for future requests. 

Flexibility

Imgix is flexible enough to work with almost any site structure; including WordPress, Craft CMS, Shopify, React, Ruby on Rails, Python, and more (see the full list). So, whether a site is a WordPress site or a Rails application, imgix fits right into the ecosystem. And, even better: you don’t have to rebuild your web app or website to gain the benefits of image performance, which can save you a lot of time and money.

Setting up imgix on an existing website is easy. Imgix can connect to existing asset storage sources like AWS, Azure, or a web folder on the same domain. Once the image source is set up, a developer can start passing parameters to the API

Cost

Imgix is free for 1,000 images which makes it easy to integrate and grow with your site. Pricing goes to $750/yr for 5,000 images and $3,000/yr for 25,000 images. In their pricing structure, “images” are categorized as origin images, so the count only includes original images and not transformed ones. So, you could have hundreds of images and thousands of image transformations all being delivered through a CDN for free.

Conclusion

Ensuring fast site speed isn't just important. It is vital. It's the cornerstone of a successful online presence, directly influencing search engine rankings, user satisfaction, and ultimately, your return on investment. Properly sized and optimized images are key to ensuring your site loads quickly and displays correctly for users across various devices.

We have found that imgix enables our team to efficiently create projects with diverse image options, saving managers and developers valuable time. Our clients benefit from reduced server space and an increased site speed. Imgix’s API is comprehensive, so you can use one tool for all features and options around site images — from cropping and resizing to face detection and automated color palettes, to video and beyond. Having used imgix for the past five years to support the wide-ranging needs of our clients, we feel confident recommending it and using it again and again. 

Users expect a website to load fast, and imgix is a reliable way to make sure that happens. 




wit

Handling Spelling Mistakes with Postgres Full Text Search

Background #

Postgres Full Text Search (FTS) is a great way to implement site search on a website running Postgres already, without requiring additional infrastructure.

On a recent engagement with a client, we were deciding between Postgres FTS and ElasticSearch. Ultimately we chose FTS because we could spin it up without having to add extra infrastructure, as we would with ElasticSearch.

Since the project was written in Ruby on Rails, we were able to use the excellent PgSearch gem to implement FTS in ActiveRecord.

Multisearch #

As we wanted a general site search, we needed to utilize multisearch. Multisearch combines multiple ActiveRecord models into one search 'document' table that you can search against. For example, if a user searches for some search term, and the search is configured for multisearch, then every single model that we mark as multisearchable will be searched for that term at the same time. See here for more detail.

Search Features #

PgSearch allows for different search features, tsearch, trigram, and dmetaphone. The default is tsearch, which uses the built-in Postgres Full Text Search.

This was great for our use case, since it also comes with highlighting, a feature that was required. The highlighting is from a field returned by Postgres FTS, where it returns the text around the search term for context and bolds the search terms.

Spelling Mistakes #

Unfortunately, tsearch does not handle misspelled words. However, as I mentioned before, PgSearch allows for other search features!

And trigram is a feature that can be installed via a Postgres extension (pg_trgm) that does just that.

Trigram #

  • The idea behind trigram search is to split pieces of text into sets of three-letter segments, and compare the sets to one another
  • If two trigram sets are similar enough, we assume there was a spelling mistake, and return the document with the correctly-spelled term.
  • As a quick example (ignoring whitespace): Consider the word Viget. Viget would make trigrams:
[vig, ige, get]
  • Now, consider our evil twin agency, Qiget. They would make trigrams
[qig, ige, get]
  • The two trigram sets match very closely, with only one of the trigrams not being the same. Thus, if we were to compare these with pg_trgm, we could reasonably tell that anyone typing 'Qiget' must have been actually looking for 'Viget', and just misspelled it.

Working Trigram into our existing solution #

PgSearch allows us to use multiple search features at once, so we can use tsearch and trigram side by side. Note that we cannot just replace tsearch with trigram due to needing some features in tsearch that are exclusive to it. Here is what an example configuration might look like.

PgSearch.multisearch_options = {
  using: {
    tsearch: {
      prefix: true,
      highlight: {
        MaxFragments: 1
      }
    },
    trigram: { 
      only: [:content]
    }
  }
}

Trigram (and timelines) causing issues #

While it was easy to slot Trigram into our multisearch, it caused a pretty serious performance hit. We were seeing 50x-75x slower searches with both features combined than with just tsearch. We needed to find a way to balance performance with handling misspellings

At the point that handling misspellings became prioritized, the entire search feature was almost fully QA'd and about ready to go out. There wasn't much time left in the budget to find a good solution for the issue.

This thread from the PgSearch repo sums it up pretty well – there were multiple other users that were/are having similar issues as we were. The top-rated comment in this thread is someone mentioning that the solution was to just use ElasticSearch ('top-rated' is doing a lot of heavy lifting. It did have the most likes...at two). We needed to find some sort of middle ground solution that we could act on quickly.

Postgres Documentation saves the day #

In the docs for the Trigram Postgres extension, the writers give an idea for using Trigram in conjunction with Full Text Search. The general idea is to create a separate words table that has a Trigram index on it.

Something like this worked for us. Note that we added an additional step with a temporary table. This was to allow us to filter out words that included non-alphabet characters.

execute <<-SQL
  -- Need to make a temp table so we can remove non-alphabet characters like websites
  CREATE TEMP TABLE temp_words AS
    SELECT word FROM ts_stat('SELECT to_tsvector(''simple'', content) FROM pg_search_documents');

  CREATE TABLE pg_search_words (
    id SERIAL PRIMARY KEY,
    word text
  );

  INSERT INTO pg_search_words (word)
    SELECT word
    FROM temp_words
    WHERE word ~ '^[a-zA-Z]+$';
  
  CREATE INDEX pg_words_idx ON pg_search_words USING GIN (word gin_trgm_ops);
  
  DROP TABLE temp_words;
SQL

This words table is therefore populated with every unique word that exists in your search content table. For us, this table was pretty large.

result = ActiveRecord::Base.connection.execute("SELECT COUNT(*) FROM pg_search_words").first['count']
puts result.first['count']
# => 1118644

Keeping the words table up-to-date #

As mentioned in the docs, this table is separate from your search table. Therefore, it needs to be either periodically regenerated or at least have any new words added to search content also added to this table.

One way to achieve this is with a trigger, which adds all new words (still filtering out non-alphabet characters) that are inserted into the documents table to the words table

create_trigger("pg_search_documents_after_insert_update_row_tr", generated: true, compatibility: 1)
  .on("pg_search_documents")
  .after(:insert, :update) do
  <<-SQL_ACTIONS
    CREATE TEMP TABLE temp_words AS
      SELECT word FROM ts_stat('SELECT to_tsvector(''simple'', ' || quote_literal(NEW.content) || ')');

    INSERT INTO pg_search_words (word)
      SELECT word
      FROM temp_words
      WHERE word ~ '^[a-zA-Z]+$';

    DROP TABLE temp_words;
  SQL_ACTIONS

end

Note that this does not handle records being deleted from the table – that would need to be something separate.

How we used the words table #

Assuming for simplicity the user's search term is a single word, if the search returns no results, we compare the search term's trigram set to the trigram index on the words table, and return the closest match.

Then, we'd show the closest match in a "Did you mean {correctly-spelled word}?" that hyperlinks to a search of the correctly-spelled word

Given more time, I would have liked to explore options to speed up the combined FTS and Trigram search. I'm certain we could have improved on the performance issues, but I can't say for sure that we could have gotten the search time down to a reasonable amount.

A future enhancement that would be pretty simple is to automatically search for that correctly-spelled word, removing the prompt to click the link. We could also change the text to something like "Showing results for {correctly-spelled word}".

Ultimately, I think with the situation at hand, we made the right call implementing Trigram this way. The search is just as fast as before, and now in the case of misspellings, a user just has to follow the link to the correctly-spelled word and they will see the results they wanted very quickly.




wit

How we use DDEV, Vite and Tailwind with Craft CMS

In 2022 we changed our dev tooling for new Craft CMS projects. Goodbye complex esoteric Webpack configuration, hello Vite. Goodbye complex esoteric Docker Compose configuration, hello DDEV. This small change in tooling has completely transformed our development experience. We start work faster and avoid wasting billable time debugging Webpack and Docker.

From Webpack to Vite #

Webpack has been the defacto way of bundling JavaScript and front end assets. It’s a powerful tool… but with that great power comes great responsibility complexity.

Vite bills itself as the “next generation” of frontend tooling. Vite is much faster at bundling. But more importantly… its default configurations work great for most website projects.

Before (Webpack) #

Well over 300 lines of configuration spanning three files. Good luck making changes!

After (Vite) #

A crisp 30 - 50 lines of code. Want to switch to TypeScript? Need to drop in a popular front-end framework? Easy! All it takes is adding a plugin and 2-3 lines of config.

Deleting old code has never felt this good!

From Docker to DDEV #

Docker is another development staple. It isolates server infrastructure into virtual “containers.” This helps avoid issues that arise from each developer having a slightly different setup. However, Docker can have a learning curve. Config changes, PHP upgrades and unexpected issues often eat up precious project time.

Enter DDEV! DDEV describes itself as “Container superpowers with zero required Docker skills: environments in minutes, multiple concurrent projects, and less time to deployment.” We’ve found that statement to be 100% true.

Before (Docker) #

Every Craft project has a different Docker config. Bugs and upgrades required deep Docker experience. Last (but not least), it was difficult to run several projects at one time (ports often conflict).

After (DDEV) #

Performance is consistently better than our hand-rolled setup thanks to Mutagen and faster DB import/exports. Simultaneous projects run out of the box. DDEV provides (and maintains) a growing list of helpful shortcuts and DX features.

Getting started #

Ready to make the switch? Here’s how to set up DDEV, Vite and Tailwind on your own Craft project.

Show me the config files already! #

If you would rather see full config files instead of following step by step, check out our Craft Site Starter on GitHub.

DDEV #

Let’s set up a fresh DDEV project and start customizing.

  1. Make sure you have DDEV installed on your computer.
  2. If you’re a PHPStorm user, install the exceedingly helpful DDEV plugin. VS Code users have a similar plugin too!
  3. Follow Craft’s guide for creating a new project (they love DDEV too).

Now you have a fresh .ddev/config.yaml just waiting to be customized.

Node Version #

Open your DDEV config and make sure your Node JS version matches Vite’s recommendations.

nodejs_version: '20' # Vite 5 expects Node 18+

Ports for Vite’s dev server #

Next, expose ports that Vite’s dev server uses will use to serve assets.

web_extra_exposed_ports:
  - name: vite
    container_port: 3000
    http_port: 3000
    https_port: 3001

Routing ports can sometimes be confusing. This diagram might help!

  • Vite’s dev server runs inside of DDEV’s web container (a Docker container).
  • Until we expose these extra ports, any custom port within DDEV is unavailable to your host machine (your computer).
  • When it’s time to configure Vite, we’ll use port 3000
  • HTTP and HTTPS traffic must use separate ports.
  • We use port 3000 for http traffic and 3001 for https

Run Vite automatically #

Usually, you’ll want Vite to watch and build files automatically after you start a DDEV project. Using web_extra_daemons adds a separate background process (daemon) for Vite.

web_extra_daemons:
  # Run Vite in a separate process
  - name: 'vite'
    command: 'npm install && npm run dev'
    directory: /var/www/html

Use hooks to improve DX #

DDEV’s powerful hooks system can run tasks before or after various DDEV commands. These post-start tasks keep dependencies and schemas up to date every time you start DDEV.

hooks:
  post-start:
    - composer: install # Keeps installed packages up to date
    - exec: ./craft up # Apply migrations & project config changes

Time for Vite #

Vite is a Node app that’s installed with NPM. Your project will need a package.json. If you don’t have one set up yet, follow NPMs initialization script.

ddev npm init

# Don't forget to ignore node_modules!
echo node_modules >> .gitignore

????Why ddev at the start of the command? This let’s us run NPM from within DDEV’s Docker containers. This means you’ll always be using the Node version configured for this project. DDEV has a bunch of shortcuts and aliases for running CLI commands (such as npm, yarn, craft and composer).

Make sure your NPM package is configured for ES Modules #

Our various config files will be using ES Module syntax for imports and exports.

ddev npm pkg set type=module

Install Vite! #

ddev npm install --save-dev vite

Add convenience scripts to package.json #

"scripts": {
  "dev": "vite",
  "build": "vite build"
}

npm run dev runs Vite in dev mode. It watches and builds your files every save. Files are served through Vite’s dev server.

npm run build bundles your JavaScript, CSS and static images for production. Your deploy process will usually call this script.

Configure vite.config.js #

Running Vite for a server rendered CMS requires some extra configuration. These options put production files in the right spot and keeps Vite’s dev server running on a specific port.

import { defineConfig, loadEnv } from 'vite'

// Match ports in .ddev/config.yaml and config/vite.php
const HTTP_PORT = 3000
const HTTPS_PORT = 3001

export default defineConfig(({ command, mode }) => {
  const env = loadEnv(mode, process.cwd(), '')

  return {
    // In dev mode, we serve assets at the root of https://my.ddev.site:3000
    // In production, files live in the /dist directory
    base: command === 'serve' ? '' : '/dist/',
    build: {
      manifest: true,
      // Where your production files end up
      outDir: './web/dist/',
      rollupOptions: {
        input: {
          // The entry point for Vite, we'll create this file soon
          app: 'src/js/app.js',
        },
      },
    },
    server: {
	    // Special address that respond to all network requests
      host: '0.0.0.0',
	    // Use a strict port because we have to hard code this in vite.php
      strictPort: true,
      // This is the port running "inside" the Web container
      // It's the same as continer_port in .ddev/config.yaml
      port: HTTP_PORT,
      // Setting a specific origin ensures that your fonts & images load
      // correctly. Assumes you're accessing the front-end over https
      origin: env.PRIMARY_SITE_URL + ':' + HTTPS_PORT,
    },
  }
})

Add JavaScript and CSS files (Entrypoint) #

Vite needs an entry point to determine what JavaScript, CSS and Front End assets it needs to compile. Remember src/js/app.js that we defined in vite.config.js? Let's make that file now.

/* Make a file in src/js/app.js */

import '../css/app.css'

console.log('Hello Craft CMS')

We’ll also add our CSS as an import in app.js . In plain-old-JavaScript you can’t import CSS files. However, Vite uses this to figure out CSS dependencies for the project.

Once Vite builds everything for production, you end up with a separate CSS file. The Craft Vite plugin includes this automatically with along your JavaScript bundle.

/* Make a file in src/css/app.css */

body {
	background-color: peachpuff;
}

Install the Vite Craft Plugin #

ddev composer require nystudio107/craft-vite
ddev craft plugin/install vite

Vite assets have different URLs in dev mode vs. production. In dev mode, assets are served from Vite’s dev server. It uses the ports that we defined in our DDEV & Vite configs.

When Vite builds for production, filenames are hashed (app.js becomes app-BZi_KJSq.js). These hashes change when the contents of the file changes. Browser can cache these files indefinitely. When an asset changes, a whole new file is served.

To help find these hashed filenames, Vite creates a manifest.json file. The manifest associates the name of your asset src/js/app.js to the hashed file that ends up on your server web/dist/assets/app-BZi_KJSq.js

The Craft Vite Plugin by NYStudio107 takes care of all this routing for you.

{
  "src/js/app.js": {
    "file": "assets/app-BZi_KJSq.js",
    "name": "app",
    "src": "src/js/app.js",
    "isEntry": true,
    "css": ["assets/app-BXePGY5I.css"]
  }
}

Configure the Vite Craft Plugin #

Make a new plugin config file in config/vite.php

<?php

use crafthelpersApp;

// Use the current host for dev server requests. Otherwise fall back to the primary site.
$host = Craft::$app->getRequest()->getIsConsoleRequest()
    ? App::env('PRIMARY_SITE_URL')
    : Craft::$app->getRequest()->getHostInfo();

return [
    'devServerPublic' => "$host:3001", // Matches https_port in .ddev/config.yaml
    'serverPublic' => '/dist/',
    'useDevServer' => App::env('CRAFT_ENVIRONMENT') === 'dev',
    'manifestPath' => '@webroot/dist/.vite/manifest.json',
    // Optional if using React or Preact
    // 'includeReactRefreshShim' => true,
];

Include your Vite bundles in Twig #

The script and asset functions includes the appropriate files depending on in if you’re in dev mode or production. Clear out your templates/index.twig file and add the following snippet to your <head> tag.

{# Load our main CSS file in dev mode to avoid FOUC #}
{% if craft.vite.devServerRunning() %}
    <link rel="stylesheet" href="{{ craft.vite.asset("src/css/app.css") }}">
{% endif %}

{{ craft.vite.script('src/js/app.js', false) }}

Whew! ???? We’re at a point now where we can test our integration. Run ddev restart and then ddev launch . You should see “Hello Craft CMS” in your browser console.


Setup Tailwind #

Now that Vite is processing src/css/app.css, it’s time to install Tailwind and really get cooking.

These steps are based on Tailwind’s official installation guide. But make sure to run all commands from within DDEV.

Install packages #

ddev npm install -D tailwindcss postcss cssnano autoprefixer
# No DDEV shortcut for npx :(
ddev exec npx tailwindcss init -p

Configure template paths in tailwind.config.js #

/** @type {import('tailwindcss').Config} */
export default {
	// Watch Twig templates and any JS or JSX that might use Tailwind classes.
  content: ['./templates/**/*.twig', './src/**/*.{js,jsx,ts,tsx,svg}'],
  theme: {
    extend: {},
  },
  plugins: [],
}

Configure postcss.config.js for production #

export default {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
    ...(process.env.NODE_ENV === 'production' ? { cssnano: {} } : {})
  }
}

Add Tailwind directives to src/css/app.css #

@tailwind base;
@tailwind components;
@tailwind utilities;

You’ll most likely need to run ddev restart again to get Vite to recognize your new Tailwind config.


❓ Do i need to set up live reload of Twig? Turns out it’s already done for you! Styling a Tailwind project means editing Twig files to change styles. It’s super handy to reload your browser every time you save. Normally you’d reach for vite-plugin-restart to get this functionality. However, Tailwind’s JIT mode automatically notifies Vite when CSS has compiled and the page should reload.

That's a wrap! #

That’s all it takes to configure a minimal DDEV and Vite project! We’ve found that both of these tools are easy to extend as a project get more complo'ex. Adding things like Redis or React are just a plugin install and a few lines of config away.

???? If you'd like to see this setup (and more) in a real-world Craft CMS project, check out our Craft Site Starter on GitHub.

Go forth and Vite + DDEV to your heart’s desire.




wit

RIP a Livecast #636 – Maggot May with special guest Necrosexual

We're excited to have our friend, the most electrifying man in corpse entertainment, Necrosexual join us at the top of the show to talk about his new EP, Seeds of […]




wit

RIP a Livecast #641 – Velvet Rope with special guest Dan Ozzi

Our good friend, Dan Ozzi, is back on the show today to talk about his new book SELLOUT: The Major Label Feeding Frenzy That Swept Punk, Emo, and Hardcore (1994-2007). […]




wit

RIP a Livecast #655 – This is the Hot Stuff with special guest Alex Skolnick

This will be the last episode of the Livecast posted to Metal Injection, get future episodes at ripalivecast.com Skoly-D himself, Alex Skolnick sits in with us to chat about our […]



  • RIP a Livecast

wit

Cocktails with Don Draper, Dinner and Drinks at Oakland’s New Mid-Century Modern, Bardo Lounge and Supper Club

If, like me, you are a fan of all things mid-century modern, then you won’t want to miss Oakland’s newest Lakeshore addition, Bardo Lounge and Supper Club. Like a vintage trip with Don Draper back in time, you’ll enjoy all the little touches that make for a perfect night out for some excellent cocktails along …




wit

Google Photos — Bait Meet Switch

In case you missed it recently, Google Photos has decided to end their free unlimited photo hosting service. Beginning in June of next year users will be limited to 15GB of space before being asked to pay for more storage. How much you’ll have to pay will depend on how much storage you use. Unfortunately …




wit

Twitter vs. Flickr a View Count Comparison

Yesterday Twitter announced that they were adding view counts to tweets on Twitter. I thought I’d use this announcement to very unscientifically compare the number of views one of my photos received on Twitter vs. Flickr. While some might call this an “apples vs. oranges” comparison, and Flickr is admittedly more of a photography centric …




wit

Why Twitter’s Paid Subscription Model May Be a Smart Move

Boom! And just like that Elon Musk dropped a game changer. After several months of encouraging people to pay $7/month in the form of $84/year, Elon announced yesterday that starting April 15th, only verified Twitter accounts will be eligible to be in the “For You” tab. This was also after he announced that everyone who …




wit

Branding and Packaging Design for Di Ligúria: Italian Roots with Brazilian Flair

Branding and Packaging Design for Di Ligúria: Italian Roots with Brazilian Flair

abduzeedo

Discover the branding and packaging design of Di Ligúria, a Brazilian pizzeria, blending Italian heritage with Brazilian charm.

When two Brazilian entrepreneurs with Italian heritage set out to create Di Ligúria, a pizzeria in Belo Horizonte, they wanted more than just a menu of pizzas. They sought a brand that paid homage to the flavors, traditions, and warmth of Italian culture while embodying the lively spirit of Brazilian dining. Designer Danilo Akan took on this challenge, developing a branding and packaging design that bridges these cultural elements seamlessly.

Di Ligúria’s brand identity is grounded in a love for Italian cuisine, inspired by the founders’ Genoese roots and the culinary culture of the Liguria region. Akan crafted a visual concept that honors this Italian foundation while infusing a relaxed Brazilian vibe. The name “Di Ligúria” itself is a tribute to Italy’s Liguria region, signaling an immediate connection to Italian authenticity.

Akan’s design approach captures this dual identity, focusing on simplicity, elegance, and a playful touch. Using negative space and bold typographic elements, Akan brings the essence of Italian tradition forward, yet retains a fresh, contemporary look that appeals to a wide audience. His design balances modern aesthetics with nostalgic elements of Italian dining, creating a memorable brand that invites customers to savor the Italian experience.

The most striking element of Di Ligúria’s brand identity is its innovative typography. Akan developed a typographic style that incorporates subtle nods to pizza and pasta, the core offerings of Di Ligúria. By using negative space within the letterforms, particularly in the letter “G,” Akan brings visual references to pizza slices and pasta strands. This clever use of negative space allows the brand to visually communicate its primary products in an understated yet effective way.

The logo’s typeface is both modern and classic, giving a nod to Italian design’s timeless elegance. This typographic style doesn’t just serve as a brand marker but becomes an integral part of the visual experience, subtly reinforcing the restaurant’s Italian roots while remaining approachable.

Packaging that Enhances the Experience

In addition to branding, the packaging design plays a significant role in delivering Di Ligúria’s identity. Packaging is designed not just for functionality but as an extension of the dining experience. By integrating graphic patterns inspired by Italian motifs, Akan’s design makes every pizza box, pasta container, and salad package an experience in itself.

The patterns, echoing Italian ceramic tiles and Mediterranean styles, contribute to the visual storytelling of Di Ligúria. They evoke the charm of Italy and the idea of gathering around a table with family and friends. With packaging that feels thoughtful and distinctive, customers are reminded of the quality and heritage behind each meal.

From the moment a customer sees the logo to when they unbox a fresh pizza, Di Ligúria’s branding and packaging tell a story. Each design choice reflects the founders’ desire to create a brand that goes beyond fast food and into a cultural experience, filled with Italian warmth and Brazilian vitality. Akan’s thoughtful use of typography, graphic patterns, and packaging demonstrates how design can capture a brand’s essence and elevate the customer’s experience.

For anyone looking to explore Akan’s creative process and Di Ligúria’s full brand story, more details are available on his website.

Di Ligúria’s branding and packaging design provide an excellent example of how design can connect cultural roots with a fresh perspective. Akan’s work successfully weaves Italian traditions into a Brazilian setting, delivering a design that’s as inviting as the food it represents.

Branding and visual identity artifacts




wit

A Beautiful Spring Begins With Fall Planting

By University of Illinois News Have you ever admired the vibrant colors of spring flowers and wondered how to create this beauty in your own landscape? “The time to plant for spring bloomers is now,” said University of Illinois Extension … Continue reading




wit

Why to start email marketing with SendPulse

SendPulse is one of the leading email marketing platforms which offers integrated solutions: emails, SMS, push notifications, SMTP and API. It was launched in 2015, and now is a successful startup with representatives in 8 countries. SendPulse team offers cost and time efficient service  to over 250,000 active users including large and small businesses and … Continue reading Why to start email marketing with SendPulse

The post Why to start email marketing with SendPulse appeared first on Design Shard.




wit

How to Enable Scroll Tracking in WordPress With Google Analytics

Want to enable scroll tracking on your WordPress website? You can easily find out how far a user scrolls down on each post. This lets you know the exact section in which they lose interest and abandon your site. With this data, you can modify that specific section and make it interesting enough to engage […]

The post How to Enable Scroll Tracking in WordPress With Google Analytics first appeared on IsItWP - Free WordPress Theme Detector.




wit

Cooking with BuddyPress

I’m sitting downstairs at WordCamp 2009 in San Fransisco. Up on stage right now, Andy Peatling creator of BuddyPress. BuddyPress Notes Why BuddyPress: BYOTOS ( Bring Your Own Terms Of Service ) Custom branding Existing plugins ( WordPress plugin integration + BP specific plugins ) University Intranet Profile Activity Streams + LDAP login plugin Blog […]

The post Cooking with BuddyPress appeared first on WPCult.




wit

Podcasting with Dave Moyer

Planning Who let you in? Format Daily Weekly Monthly Hour/half hour A show’s Outline – Intro -What is this thing? Who are you Location of your podcast URL and contact Details The fun part Script or outline On the fly fix it later Ads and “breaks”? Save the good stuff What you may need: Aplications: […]

The post Podcasting with Dave Moyer appeared first on WPCult.




wit

Get Large with iOS 6

Operating system is the software that helps computers or mobile devices to run smoothly. iOS on the other hand is the mobile operating system that has been made particularly by Apple and it is applicable only for the iPhone, iPad and other related devices. It was first introduced in 2007 and with time Apple kept […]

The post Get Large with iOS 6 appeared first on WPCult.




wit

Grow Your Real Estate Business With Pinterest

Pinterest is a social media website where users share their favorite images from around the web with their followers. Rather than using words to express themselves, Pinterest users use images and photographs instead. Like other forms of social media, Pinterest offers a unique opportunity for real estate agents looking to grow their businesses. With so […]

The post Grow Your Real Estate Business With Pinterest appeared first on WPCult.




wit

Build Design Systems With Penpot Components

In today’s turbulent landscape of design, Penpot stands out with its commitment to open-source, free unlimited access, and its unique, robust features. An example could be its new components system that takes another leap forward in aligning design with code. Let's dive into how it empowers both designers and developers to create more maintainable and scalable design systems.




wit

How To Build A Multilingual Website With Nuxt.js

Handling translations for multilingual websites is famously difficult and, yet, crucial for many companies and organizations that serve a global audience. Thankfully, modern tooling abstracts away a great deal of the work, allowing for seamless translations that dynamically update the rendered content on a page, as demonstrated in this step-by-step tutorial.




wit

Creating Custom Lottie Animations With SVGator

Creating ready-to-implement Lottie animations with a single tool is now possible thanks to SVGator’s latest feature updates. In this article, you will learn how to create and animate a Lottie using SVGator, an online animation tool that has zero learning curve if you’re familiar with at least one design tool.




wit

Interview With Björn Ottosson, Creator Of The Oklab Color Space

Go behind the scenes with Björn Ottosson, the Swedish engineer who created Oklab color space, and discover how he developed a simple yet effective model with good hue uniformity while also handling lightness and saturation well — and is “okay” to use.




wit

It’s Here! How To Measure UX &amp; Design Impact, With Vitaly Friedman

Design decisions shouldn’t be a matter of personal preference. We can use reliable design KPIs and UX metrics to guide and shape our design work and measure its impact on business. Meet How To Measure UX and Design Impact, our new video course that helps with just that.




wit

‘A World Without Clouds. Think About That a Minute’: New Study Details Possibility of Devastating Climate Feedback Loop

By Jessica Corbett Common Dreams “We face a stark choice [between] radical, disruptive changes to our physical world or radical, disruptive changes to our political and economic systems to avoid those outcomes.” As people across the globe mobilize to demand … Continue reading




wit

SCHOOL OF NATURE: 8 Ways to Jumpstart a Great School Year with a Dose of Vitamin N

By Richard Louv Children & Nature Network A Natural Teacher is anyone who uses the power of nature as an environment for learning – not only about nature, but about any subject. Professional educators, parents, grandparents, librarians, park rangers, the … Continue reading




wit

NASA Celebrates Earth Day with Public Events, Online Activities

By PRNewswire-USNewswire This year, NASA will celebrate Earth Day, April 22, with a variety of live and online activities Thursday and Friday, April 20-21, to engage the public in the agency’s mission to better understand and protect our home planet. … Continue reading




wit

With Trump, Israel Pushes to Annex West Bank

Israel's far-right finance minister, Bezalel Smotrich, has ordered preparations for the annexation of settlements in the Israeli-occupied West Bank. President-elect Donald Trump's victory in the US election "brings an important opportunity for the State of Israel," Smotrich told the Knesset, or Israeli parliament.




wit

[Podcast] Humour in Branding with Paddy Gilmore

Discover how clever humor can enhance brand identity, engage audiences, and create memorable marketing campaigns.




wit

Streamline Your Design Workflow with Adobe’s Creative Cloud Libraries and New AI-Powered Tools

Thanks to the AI-powered Adobe Creative Cloud Libraries, creatives can now simplify workflows and design processes in seconds!





wit

Lost without you Mummy


Lost without you Mummy, originally uploaded by !efatima.




wit

How to Boost Search Visibility With Life Science SEO

In today’s constantly evolving digital landscape, search engine optimization (SEO) has emerged as a critical tool for enhancing online visibility and bringing more eyes to your content.  Implementing SEO strategies in life science marketing goes beyond simple rankings and clicks, though. It’s about providing valuable, user-focused content that resonates with the target audience you want […]

The post How to Boost Search Visibility With Life Science SEO appeared first on 3.7 Designs.




wit

Transforming Tech with Digital Marketing: Gaining a Competitive Edge

Digital marketing is an essential part of how today’s tech companies reach customers. A tailored digital marketing strategy can provide high value content to potential customers while also demonstrating the need and effectiveness of your offerings. This article dives into the importance of digital marketing for tech companies and the most important tactics and platforms […]

The post Transforming Tech with Digital Marketing: Gaining a Competitive Edge appeared first on 3.7 Designs.




wit

The Problem with Plastics

This infographic shares the depressing small amount of plastic that gets recycled. Information is Beautiful created The Problem with Plastics infographic by visualizing data by Geyer et al, Science Advances, back in 2017. The infographic uses a Sankey Diagram to show the fate of all plastics that were ever made.

Why plastic recycling doesn’t work ????

“Most ‘recycled’ plastic still ends up being dumped or incinerated”

n.b. These numbers are from 2017. Humanity produces approx. 345 million tonnes of plastic a year. That means another ~1.7 billion tonnes since this study was released.

Found on Informationisbeautiful.net




wit

How Long Can People Cover Their Needs Without Income?

How Long Can People Cover Their Needs Without Income? infographic by Visual Capitalist.

How Long Can People Cover Their Needs Without Income?

With nearly half of people under 34 worldwide unable to cover their needs for a month or less without income, it is no surprise that financial resiliency is a hot topic.

So, for this graphic, Visual Capitalist has partnered with Lloyd’s Register Foundation to explore economic resilience further and determine how long the average person can afford to cover their needs without income.

World Risk Poll 2024 Report: Economic Resilience

Lloyd’s Register Foundation produces the World Risk Poll every two years in partnership with Gallup, and the World Risk Poll 2024 report explores the everyday risks of 147,000 people from 142 nations.

They asked respondents how long they could afford to cover basic needs, such as food, transport, and shelter, if they lost all income. 

The results reveal a distinct trend across all age groups, with respondents typically falling into two categories: those with one month or less of financial runway, and those with more than four months. Relatively fewer respondents reported being able to survive two to three months.

I think this is a really interesting adaptation of a Sankey/Alluvial diagram. I’d like to see summaries of each timeframe to support their discussion around trends.

Found on Visual Capitalist.




wit

Easily Organize Your Photos with Post Order

There are many reasons why you may want to organize WordPress photos, or change the order of your photography store’s products. You can attention to older products, or increase conversions by showcasing popular items more prominently. Unfortunately, by default, changing the published date of each product is the only way to adjust the order of products in […]




wit

How to Set Up the Sell Media S3 Extension with WordPress

Cloud storage has become immensely popular, especially for hosting hefty files such as images and video. There are numerous benefits to storing your content on a dedicated server, and for offering downloads that are both consistently quick and secure, cloud storage is vital. We’ve developed our Sell Media plugin to help you sell images and video on your WordPress website – and by […]




wit

How to Build a Stock Photo Business With WordPress

Selling your photography can be a great way to funnel your passion into a business. However, the web is awash in stock photography sites that curate photos from thousands of photographers. To stand out, you might be better off going your own way. And with the right tools—such as WordPress and Sell Media—you can build your own stock photo […]




wit

How to Sync Your Photos in Lightroom With WordPress

There’s no doubt that we’re spoilt for choice when it comes to powerful photo editing software – for instance, Adobe Photoshop Lightroom provides astounding functionality at a relatively cheap price. The same can be said for creating websites, especially when using WordPress. However, combining them effectively as one solution for managing your photos is just […]




wit

How to Integrate Squarespace with WordPress (In 5 Steps)

Squarespace is a useful platform for many users. It’s easy to use, possesses some excellent features, and looks modern to boot. That being said, there’s no need to limit yourself to using a single platform in order to harness various aspects of its functionality. If you don’t mind a little work, it’s entirely possible to integrate Squarespace with […]




wit

How to Integrate Wix with WordPress

Integrating Wix with WordPress is easier than one might think, but there are a few potential issues to look out for. For those who don’t know, Wix is one of the easiest platforms for beginners to create websites with. It offers a highly intuitive builder and attractive designs, but it’s not the only option available. […]




wit

How to Integrate Weebly with WordPress (In 4 Short Steps)

Weebly is one of the most beginner-friendly platforms when it comes to web development. It enables newcomers to build stylish and usable sites, but it’s not the most feature-intensive solution around. For more power, you’ll need to turn to a platform such as WordPress. While Weebly does offer a wide variety of features, it’s not a platform built […]