Archive

Archive for the ‘’ Category

The Era Of Platform Primitives Is Finally Here

May 28th, 2024 No comments

This article is a sponsored by Netlify

In the past, the web ecosystem moved at a very slow pace. Developers would go years without a new language feature or working around a weird browser quirk. This pushed our technical leaders to come up with creative solutions to circumvent the platform’s shortcomings. We invented bundling, polyfills, and transformation steps to make things work everywhere with less of a hassle.

Slowly, we moved towards some sort of consensus on what we need as an ecosystem. We now have TypeScript and Vite as clear preferences—pushing the needle of what it means to build consistent experiences for the web. Application frameworks have built whole ecosystems on top of them: SolidStart, Nuxt, Remix, and Analog are examples of incredible tools built with such primitives. We can say that Vite and TypeScript are tooling primitives that empower the creation of others in diverse ecosystems.

With bundling and transformation needs somewhat defined, it was only natural that framework authors would move their gaze to the next layer they needed to abstract: the server.

Server Primitives

The UnJS folks have been consistently building agnostic tooling that can be reused in different ecosystems. Thanks to them, we now have frameworks and libraries such as H3 (a minimal Node.js server framework built with TypeScript), which enables Nitro (a whole server runtime powered by Vite, and H3), that in its own turn enabled Vinxi (an application bundler and server runtime that abstracts Nitro and Vite).

Nitro is used already by three major frameworks: Nuxt, Analog, and SolidStart. While Vinxi is also used by SolidStart. This means that any platform which supports one of these, will definitely be able to support the others with zero additional effort.

This is not about taking a bigger slice of the cake. But making the cake bigger for everyone.

Frameworks, platforms, developers, and users benefit from it. We bet on our ecosystem together instead of working in silos with our monolithic solutions. Empowering our developer-users to gain transferable skills and truly choose the best tool for the job with less vendor lock-in than ever before.

Serverless Rejoins Conversation

Such initiatives have probably been noticed by serverless platforms like Netlify. With Platform Primitives, frameworks can leverage agnostic solutions for common necessities such as Incremental Static Regeneration (ISR), Image Optimization, and key/value (kv) storage.

As the name implies, Netlify Platform Primitives are a group of abstractions and helpers made available at a platform level for either frameworks or developers to leverage when using their applications. This brings additional functionality simultaneously to every framework. This is a big and powerful shift because, up until now, each framework would have to create its own solutions and backport such strategies to compatibility layers within each platform.

Moreover, developers would have to wait for a feature to first land on a framework and subsequently for support to arrive in their platform of choice. Now, as long as they’re using Netlify, those primitives are available directly without any effort and time put in by the framework authors. This empowers every ecosystem in a single measure.

Serverless means server infrastructure developers don’t need to handle. It’s not a misnomer, but a format of Infrastructure As A Service.

As mentioned before, Netlify Platform Primitives are three different features:

  1. Image CDN
    A content delivery network for images. It can handle format transformation and size optimization via URL query strings.
  2. Caching
    Basic primitives for their server runtime that help manage the caching directives for browser, server, and CDN runtimes smoothly.
  3. Blobs
    A key/value (KV) storage option is automatically available to your project through their SDK.

Let’s take a quick dive into each of these features and explore how they can increase our productivity with a serverless fullstack experience.

Image CDN

Every image in a /public can be served through a Netlify function. This means it’s possible to access it through a /.netlify/images path. So, without adding sharp or any image optimization package to your stack, deploying to Netlify allows us to serve our users with a better format without transforming assets at build-time. In a SolidStart, in a few lines of code, we could have an Image component that transforms other formats to .webp.

import { type JSX } from "solid-js";

const SITE_URL = "https://example.com";

interface Props extends JSX.ImgHTMLAttributes<HTMLImageElement> {
  format?: "webp" | "jpeg" | "png" | "avif" | "preserve";
  quality?: number | "preserve";
}

const getQuality = (quality: Props["quality"]) => {
  if (quality === "preserve") return"";
  return &q=${quality || "75"};
};

function getFormat(format: Props["format"]) {
  switch (format) {
    case "preserve":
      return"  ";
    case "jpeg":
      return &fm=jpeg;
    case "png":
      return &fm=png;
    case "avif":
      return &fm=avif;
    case "webp":
    default:
      return &fm=webp;
  }
}

export function Image(props: Props) {
  return (
    <img
      {...props}
      src={${SITE_URL}/.netlify/images?url=/${props.src}${getFormat(
        props.format
      )}${getQuality(props.quality)}}
    />
  );
}

Notice the above component is even slightly more complex than bare essentials because we’re enforcing some default optimizations. Our getFormat method transforms images to .webp by default. It’s a broadly supported format that’s significantly smaller than the most common and without any loss in quality. Our get quality function reduces the image quality to 75% by default; as a rule of thumb, there isn’t any perceivable loss in quality for large images while still providing a significant size optimization.

Caching

By default, Netlify caching is quite extensive for your regular artifacts – unless there’s a new deployment or the cache is flushed manually, resources will last for 365 days. However, because server/edge functions are dynamic in nature, there’s no default caching to prevent serving stale content to end-users. This means that if you have one of these functions in production, chances are there’s some caching to be leveraged to reduce processing time (and expenses).

By adding a cache-control header, you already have done 80% of the work in optimizing your resources for best serving users. Some commonly used cache control directives:

{
  "cache-control": "public, max-age=0, stale-while-revalidate=86400"

}
  • public: Store in a shared cache.
  • max-age=0: resource is immediately stale.
  • stale-while-revalidate=86400: if the cache is stale for less than 1 day, return the cached value and revalidate it in the background.
{
  "cache-control": "public, max-age=86400, must-revalidate"

}
  • public: Store in a shared cache.
  • max-age=86400: resource is fresh for one day.
  • must-revalidate: if a request arrives when the resource is already stale, the cache must be revalidated before a response is sent to the user.

Note: For more extensive information about possible compositions of Cache-Control directives, check the mdn entry on Cache-Control.

The cache is a type of key/value storage. So, once our responses are set with proper cache control, platforms have some heuristics to define what the key will be for our resource within the cache storage. The Web Platform has a second very powerful header that can dictate how our cache behaves.

The Vary response header is composed of a list of headers that will affect the validity of the resource (method and the endpoint URL are always considered; no need to add them). This header allows platforms to define other headers defined by location, language, and other patterns that will define for how long a response can be considered fresh.

The Vary response header is a foundational piece of a special header in Netlify Caching Primitive. The Netlify-Vary will take a set of instructions on which parts of the request a key should be based. It is possible to tune a response key not only by the header but also by the value of the header.

  • query: vary by the value of some or all request query parameters.
  • header: vary by the value of one or more request headers.
  • language: vary by the languages from the Accept-Language header.
  • country: vary by the country inferred from a GeoIP lookup on the request IP address.
  • cookie: vary by the value of one or more request cookie keys.

This header offers strong fine-control over how your resources are cached. Allowing for some creative strategies to optimize how your app will perform for specific users.

Blob Storage

This is a highly-available key/value store, it’s ideal for frequent reads and infrequent writes. They’re automatically available and provisioned for any Netlify Project.

It’s possible to write on a blob from your runtime or push data for a deployment-specific store. For example, this is how an Action Function would register a number of likes in store with SolidStart.

import { getStore } from "@netlify/blobs";
import { action } from "@solidjs/router";

export const upVote = action(async (formData: FormData) => {
  "use server";

  const postId = formData.get("id");
  const postVotes = formData.get("votes");

  if (typeof postId !== "string" || typeof postVotes !== "string") return;

  const store = getStore("posts");
  const voteSum = Number(postVotes) + 1)

  await store.set(postId, String(voteSum);

  console.log("done");
  return voteSum

});

Final Thoughts

With high-quality primitives, we can enable library and framework creators to create thin integration layers and adapters. This way, instead of focusing on how any specific platform operates, it will be possible to focus on the actual user experience and practical use-cases for such features. Monoliths and deeply integrated tooling make sense to build platforms fast with strong vendor lock-in, but that’s not what the community needs. Betting on the web platform is a more sensible and future-friendly way.

Let me know in the comments what your take is about unbiased tooling versus opinionated setups!

Categories: Others Tags:

3 Essential Design Trends, June 2024

May 27th, 2024 No comments

Summer is off to a fun start with some highly dramatic website design trends showing up in projects. Let’s dive in!

Categories: Designing, Others Tags:

Switching It Up With HTML’s Latest Control

May 24th, 2024 No comments

The web is no stranger to taking HTML elements and transforming them to look, act, and feel like something completely different. A common example of this is the switch, or toggle, component. We would hide a checkbox beneath several layers of styles, define the ARIA role as “switch,” and then ship. However, this approach posed certain usability issues around indeterminate states and always felt rather icky. After all, as the saying goes, the best ARIA is no ARIA.

Well, there is new hope for a native HTML switch to catch on.

Safari Technology Preview (TP) 185 and Safari 17.4 released with an under-the-radar feature, a native HTML switch control. It evolves from the hidden-checkbox approach and aims to make the accessibility and usability of the control more consistent.

<!-- This will render a native checkbox --//>
<input type="checkbox" />

<!-- Add the switch attribute to render a switch element --//>
<input type="checkbox" switch />
<input type="checkbox" checked switch />

Communication is one aspect of the control’s accessibility. Earlier in 2024, there were issues where the switch would not adjust to page zoom levels properly, leading to poor or broken visibility of the control. However, at the time I am writing this, Safari looks to have resolved these issues. Zooming retains the visual cohesion of the switch.

The switch attribute seems to take accessibility needs into consideration. However, this doesn’t prevent us from using it in inaccessible and unusable ways. As mentioned, mixing the required and indeterminate properties between switches and checkboxes can cause unexpected behavior for people trying to navigate the controls. Once again, Adrian sums things up nicely:

“The switch role does not allow mixed states. Ensure your switch never gets set to a mixed state; otherwise, well, problems.”

— Adrian Roselli

Internationalization (I18N): Which Way Is On?

Beyond the accessibility of the switch control, what happens when the switch interacts with different writing modes?

When creating the switch, we had to ensure the use of logical CSS to support different writing modes and directions. This is because a switch being in its right-most position (or inline ending edge) doesn’t mean “on” in some environments. In some languages — e.g., those that are written right-to-left — the left-most position (or inline starting edge) on the switch would likely imply the “on” state.

While we should be writing logical CSS by default now, the new switch control removes that need. This is because the control will adapt to its nearest writing-mode and direction properties. This means that in left-to-right environments, the switch’s right-most position will be its “on” state, and in right-to-left environments, its left-most position will be the “on” state.

See the Pen Safari Switch Control – Styling [forked] by @DanielYuschick.

Final Thoughts

As we continue to push the web forward, it’s natural for our tools to evolve alongside us. The switch control is a welcome addition to HTML for eliminating the checkbox hacks we’ve been resorting to for years.

That said, combining the checkbox and switch into a single input, while being convenient, does raise some concerns about potential markup combinations. Despite this, I believe this can ultimately be resolved with linters or by the browsers themselves under the hood.

Ultimately, having a native approach to switch components can make the accessibility and usability of the control far more consistent — assuming it’s ever supported and adopted for widespread use.

Categories: Others Tags:

How Small Businesses Can Navigate Tax Season With Ease

May 24th, 2024 No comments

If you’re like a lot of small-business owners, you’re still recovering from the stress and chaos of tax season. If you gathered documents at the last minute or received a bigger bill than you expected, you were probably as much a victim of your lack of preparation as you were of the IRS.

There’s a better way to handle your small-business taxes. It involves a mix of common sense, solid year-round financial planning, professional tax prep, simple document tracking, and staying on top of the latest changes in the tax code. 

Here are eight easy tips for small businesses to navigate tax season with ease. 

1. Use a professional

Americans have a pretty pessimistic economic outlook in 2024, even though the economy is actually improving. As a result, many business owners are trying to pare back their expenses. One of the first services to go is often the tax accountant because many small-business owners think they can do their business taxes themselves. 

This might be true, but it doesn’t mean it’s a great idea. Having a professional handle your tax prep is actually one of the most valuable professional services that a small business can buy. A good tax pro will not only prepare your taxes at tax time, but he or she can also help you get your paperwork in order year-round and make sure you’re using proper accounting practices. 

Even if you have some kind of professional expertise that would enable you to handle your business taxes yourself, you need to consider if the time you’d spend on your taxes would be better spent on the core functions of your business. 

2. Don’t wait until the last minute

Doing your taxes isn’t something you do once a year. It’s a year-round concern. You should be tracking all your expenses, receipts, and financial documents throughout the year, as well as actively carrying out tax-planning strategies. Do this right, and you’ll be able to navigate tax season without all the stress. 

On the other hand, if you let bad spending habits from your personal life spill over into how you run your business, you’re setting yourself up for a rough tax season. Gathering and organizing all your invoices and receipts is a frustrating and time-consuming process, and it’s inevitable that you’re going to cost yourself money by losing out on key tax deductions. 

3. Use last year’s blueprint

If this is your first year as a small business, you’re going to essentially start from scratch at tax time. In subsequent years, though, you can use that strategy as a blueprint if it worked well. Get the same documents together, and then ask yourself — or your tax accountant — what’s changed and then go get those documents. Rather than starting at zero every year, this is an easy way to cover the basics and can save you a lot of hours. 

4. Keep your team in the loop

If you’re serious about tax planning, you should check in with your tax accountant once a quarter. This has a variety of benefits. One, it will force you to put together a preliminary financial statement that will include your profits and losses, as well as your main expenses. This gives you and your tax pro a snapshot of your business and is a great opportunity for course corrections. Some small businesses even prefer to handle their bookkeeping on a quarterly basis, so you’ll reconcile your books four times a year. 

Second, it gives your tax accountant a preview of what they’ll be handling at tax time. This is especially important if you’re expanding or if your major assets are changing. 

Third, it’s a chance to talk about your current tax strategies, such as the deductions you’re targeting and if they’re compatible with the trajectory of your business goals. Touching base throughout the year is the best way to avoid getting hit with unpleasant surprises at tax time.

5. Don’t overlook obscure credits and obligations

The tax code changes constantly, so make sure you and your tax pro are on top of the latest changes that affect your small business.

For example, you could be eligible for lucrative tax credits related to energy efficiency or hiring. Make sure you’re exploring these possibilities. 

Another area of recent change is the use of remote workers. If you have remote employees, you’ll need to make sure you’re in compliance with all the state and federal tax obligations related to them, which can often be counterintuitive. 

6. Send your invoices

Outstanding payments can be frustrating, especially if you get hit with a big tax bill. Try to collect your unpaid invoices ahead of tax time so you can wrap up all the loose ends from the previous tax year. Consider using accounting software that sends automatic payment requests so you don’t have to spend your time chasing down payments. 

7. Use separate accounts

Maintain strict separation between your business and personal accounts throughout the year. Put your business expenses on your dedicated business credit card or checking account only, and never use those accounts for your personal expenses. 

This will make your accounting much easier because your expenses will already be separated. It also sends the right message to the IRS, which might be assessing whether your business is run for profit or as a hobby — a distinction that can have profound implications on your business’ tax status.

8. Set aside a surplus or open a line of credit

Part of tax planning is planning how to pay your taxes. The reality is that no matter how carefully you conduct your bookkeeping, you could be in for a surprise at tax time. Experts suggest setting aside at least 10% more than you think you’ll need for taxes in case you’re hit with an unexpectedly high tax bill. 

If there’s any doubt about having sufficient cash on hand at tax time, open a business line of credit ahead of time. This way, your tax bill won’t adversely affect your cash flow, and you’ll have access to money that you can use to pay your taxes or for other business expenses. 

Featured Image by Kelly Sikkema on Unsplash

The post How Small Businesses Can Navigate Tax Season With Ease appeared first on noupe.

Categories: Others Tags:

How to Turn Visitors Into Loyal Customers With Full-Funnel Marketing

May 23rd, 2024 No comments

Businesses today have so many ways to reach their audience. From viral social media ads and influencer partnerships, to good old-fashioned print ads, the possibilities are virtually endless.

The problem is, more marketing channels doesn’t necessarily equate to more customers. With so many ways to market, it’s all too easy for your efforts to become spread too thin, leading to your brand voice getting drowned out.

That‘s where full-funnel marketing comes in. It’s a marketing approach designed to cover every brand touch point in the customer journey, making sure nobody falls through the cracks.

What is Full-Funnel Marketing?

Full-funnel marketing involves creating content for every stage of the marketing funnel. 

It’s based on the understanding that the customer journey through a marketing funnel isn’t usually a straight line, but more like a maze of interconnected touch points across a variety of channels.

The aim of a full-funnel strategy is to connect these touch points, providing a clear path that leads potential customers to making a purchase with your brand, regardless of the journey they took along the way.

How is Full-Funnel Marketing Different to Other Marketing Strategies?

Full-funnel marketing is a comprehensive approach to marketing, focused on guiding potential customers through every stage of the buyer’s journey, rather than honing in at one particular stage. Here are a few of the key differences between a full-funnel approach and other marketing approaches.

Full-Funnel Marketing Other Marketing Approaches
Coverage Covers the entire buyer journey, from awareness to post-purchase engagement. Often focus on specific stages of the buyer’s journey, e.g. lead generation, customer retention etc.
Targeting Different segments of the audience are targeted with different messages based on their current position in the funnel. Messages are more generalized for use across the entire funnel, or, specific messages are developed for one stage, not every stage.
Integration Multiple marketing channels are integrated to ensure full coverage across the entire funnel. Efforts are often focused on one channel, e.g. social media platforms, with less thought given to how they can work alongside other channels.
Metrics Multiple metrics are used together to track performance across the entire funnel. Individual metrics are often prioritized to assess performance at one key stage of the funnel.

Benefits of Full-Funnel Marketing

  • The ability to reach a wider audience, increasing the likelihood of finding potential customers.
  • More effective marketing materials and relevant calls-to-action that speak to customers at every stage of the buyer’s journey, boosting customer engagement and conversion rates.
  • A consistently positive customer experience that boosts brand loyalty and advocacy.
  • Increased momentum as customers journey through the sales funnel, reducing the likelihood of customer churn.
  • Better ROI than other marketing approaches; studies show full-funnel marketing provides up to 45% higher ROI than single-funnel approaches.

Crucial Elements of A Full-Funnel Marketing Strategy

Customer Journey Mapping

Mapping the journey a customer takes through your sales funnel allows you to more accurately plan for how you’ll meet them at every stage. You’ll be able to better anticipate the questions or concerns prospects may have, and generate marketing materials that address them in advance.

Customer journey mapping will also identify key moments where a prospect is likely to commit to a purchase, or fall out of the sales funnel. This allows you to focus on these points when they arrive to maximize your chances of success. 

Audience Segmentation

Customer segmentation allows you to tailor messages specifically to the different groups, giving you a greater chance of success. Customers could be segmented based on:

  • Demographics e.g. age, gender.
  • Geographic location.
  • Customer behavior, e.g. previous products viewed.
  • Likelihood to convert.

Developing Buyer Personas

Once your audience is segmented, you should strive to develop buyer personas for each individual segment. This is a general overview of what the average customer in each segment looks like, including their behaviors, concerns, and needs.

Developing these personas gives you a snapshot into the psyche of each different type of prospect, allowing you to develop more personalized marketing materials that speak directly to them.

Multi-Channel Marketing

Modern customers are spread across a wide variety of channels. The more channels you utilize, the higher the chances you’ll meet your target customers. Marketing channels you could consider expanding into include:

  • Email marketing.
  • Print adverts, e.g. magazines, newspapers.
  • Radio adverts.
  • SEO (Search Engine Optimization).
  • Social media.
  • Content marketing.
  • Affiliate marketing.

Image Sourced from Gartner

Be sure to remember that marketing efforts should be customized for the channel they appear on, just as they should be customized for the buyer persona they’re targeted to. For example, social media adverts tend to be less formal than newspaper or magazine adverts.

Additionally, considering the significance of online presence, ensuring a user-friendly website through effective web design is paramount. A well-designed website not only enhances customer experience but also plays a crucial role in establishing credibility and trust with potential customers across all stages of the funnel.

How to Implement a Full-Funnel Marketing Strategy

Top of the Funnel

The main aim at the top of the funnel (TOFU) is to introduce your target audience to your products and services, ideally beginning to build the trust that will lead to a conversion further down the line.

One of the main ways this is achieved is by building brand awareness. There are a number of key ways you can achieve this: 

  • Optimizing your content output to generate organic traffic to your website, (a SaaS content management provider or similar service may be able to help).
  • Utilizing paid advertising through TV, radio, social media, and print.
  • Developing a content marketing strategy that includes informative blog posts and articles.
  • By building a social media presence through engaging content on platforms like Instagram, Facebook, X (Twitter), and LinkedIn.

Additionally, it’s important to actively promote your website across various channels to ensure maximum visibility and traffic generation.

The top of the funnel isn’t the place to push too hard for a sale; the aim is to inform, not persuade at this point. You can meet as many customers as possible by spreading your marketing materials to all the channels your target audience can be found, informed by your buyer personas.

Middle of the Funnel

The main aim in the middle of the funnel (MOFU) is to get your target audience to seriously consider you as a purchase option, partly by highlighting what sets you apart from your competitors.

It’s useful to establish yourself as an authoritative brand in your industry at this point; one who can be trusted and knows what they’re talking about. There are a few ways this can be achieved:

  • Attending events and trade shows, which are a perfect place to meet your target customers and show off your products.
  • Developing thought-leadership content for publication on relevant blogs and websites in your industry and beyond, showing that you’re at the cutting edge of your industry.
  • Offering demos and product trials shows interested parties first-hand how they can benefit from your products and services.
  • Promoting positive reviews and testimonials shows your audience how successful others in their position have been with your help.

The middle of the funnel is also the perfect place to position yourself as an industry leader, showing off what makes your business a cut above your competitors. There are a few ways to achieve this:

  • Publishing comparison content that highlights the differences between your solutions and those of your competitors, without appearing too ‘salesy’.
  • Hosting webinars allows you to give prospects an educational experience in a manner that’s convenient to them.
  • Develop content that targets middle of the funnel keywords. This is useful for establishing better rankings on SERPs (Search Engine Results Pages) among an audience that’s still considering their options and looking to learn more, (look at some SaaS SEO studies for a look at how this can help).

Image Sourced from blog.hubspot.com

Bottom of the Funnel

Prospects who’ve reached the bottom of the funnel (BOFU) are close to closing a deal. Your aim now is to get them across that finish line.

You need to remove as many obstacles to purchase as possible at this point, employing marketing content that cements your brand as the perfect choice. You can achieve this by:

  • Offering coupons and discounts in your email marketing for prospects who are teetering right on the dodge of making a purchase.
  • Utilizing behaviorally-triggered content, such as cart abandonment emails offering free shipping, to prevent any prospects slipping through the net at the last moment.
  • Using clear calls-to-action in your marketing materials, encouraging prospects to make a purchase, or directing them to a landing page designed to give them that final push.
  • Create a customer portal to allow prospects to easily navigate through their purchase journey, access account information, and manage their transactions. 
  • Focusing on personalized content that reinforces a positive relationship with your prospect and keeps them engaged right to the end.
  • Crafting compelling landing page content that addresses any remaining concerns, showcases testimonials or success stories, and provides a seamless path to conversion.

Monitor Results

Of course, the process of full-funnel marketing continues even after the customer has made their way through the marketing funnel. It’s crucial to measure the performance of your efforts, so you can determine how successful they’ve been, and identify any potential improvements that could improve your chances of success next time.

Metrics to track include:

  • At the top of the funnel – keyword rankings, website traffic, impressions.
  • In the middle of the funnel – webinar attendance, content downloads, mailing list subscribers.
  • At the bottom of the funnel – customer acquisition cost, conversion rate, custom retention.

Capture Every Conversion With Full-Funnel Marketing

Full-funnel marketing ensures that you’re speaking to your customers at every stage of their journey, making sure no lead slips through the cracks.

By prioritizing targeted messaging and an integrated approach to marketing, full-funnel marketing widens your audience reach, boosts engagement, and fosters lasting customer loyalty. All of this ultimately adds up to offering a superior return on investment. 

Implementing it successfully often involves meticulous planning, including customer journey mapping, audience segmentation, and personalized content creation, as well as monitoring crucial marketing metrics throughout.

The investment is well worth it, though, with full-funnel marketing offering a roadmap to success in a competitive business landscape.

Featured Image by Scott Graham on Unsplash

The post How to Turn Visitors Into Loyal Customers With Full-Funnel Marketing appeared first on noupe.

Categories: Others Tags:

A Marketer’s Guide to Training ChatGPT

May 23rd, 2024 No comments

ChatGPT is a pretty impressive tool. Marketers use it in multiple ways, from writing blog posts to drawing meaningful insights from data with AI SEO tools.

Of course, when use ChatGPT to write for you, it might not use the tone and style that you use. Or, maybe the tone and style is fine, but ChatGPT misses to add important information that is needed to perform the task adequately. 

Thankfully, there are ways to train ChatGPT to use your writing style or data. On this page, we will cover the most accurate ChatGPT data training techniques.

The Role of Training Data

The training data forms the base for ChatGPT. It is crucial in fine-tuning the model and influencing how it responds.

By training ChatGPT with your specific data, you can customize the model to meet your needs and make sure it aligns with your target domain and produces responses that connect with your audience.

Although the training data shapes the model’s responses, the architecture of the model and its underlying algorithms are also key factors in how it behaves.

How to Train ChatGPT with Custom Data using OpenAI API & Python?

Follow the steps below to learn how to train an AI bot with a custom knowledge base using ChatGPT API. 

? Remember that this method requires knowledge and experience of coding, Python, and an OpenAI API key. 

Step 1: Install Python

Check if you have Python 3.0+ installed. If you don’t have Python on your device, download it.

Image Source

Step 2: Upgrade Pip

Pip is a Python package manager (a system that automates installing, configuring, upgrading, and removing computer programs). The new version of Python comes with pip pre-packaged. 

But, if you use the old version of Python, you can upgrade it to the latest version using a command.

pip3 install –upgrade –user

Step 3: Install required libraries

Run a series of commands in the Terminal application to install the required libraries.

First, install the OpenAI library.

PIP3 INSTALL OPENAI

And GPT Index (LlamaIndex)

PIP3 INSTALL GPT_INDEX

Then install PyPDF2, which will allow you to parse PDF files. 

PIP3 INSTALL PYPDF2

Finally, install Gradio, which will help you build a basic UI, allowing you to interact with ChatGPT.

??PIP3 INSTALL GRADIO

?Tip: You will need a code editor tool to edit and customize the code. You can use code editors like Notepad++ or Sublime Text according to your needs.

Step 4: Get your OpenAI API key

An OpenAI API key is a unique code that developers use to access OpenAI’s models via the API. This key helps confirm who is making the request and monitors their usage.

To get your OpenAI API key, log in to your OpenAI account & choose the API option.

From the left navigation menu, select API Keys.

Choose Create new secret key, which will generate a new API key for you. You should copy and paste it into a code editor. Note that after being generated, the secret API keys are not displayed.

Step 5: Prepare your custom data

Create a new directory named ‘docs’ in your system. Place TXT, CSV, or PDF files inside it.

Remember the token limit for free accounts in OpenAI, as more data will use more tokens.

You can add all the files you need to prepare your custom data in this directory.

Step 6: Create a script

Now, you will have to create a Python script to train ChatGPT using custom data. To create the script, use a text editor.

Write the necessary code and create a new page to enter the code. Add the OpenAI key to the code. Save the file in the same location that you have in your “docs” directory with the extension ‘app.py.’ 

Here is the code that you can copy and paste into your code editor.

from gpt_index import DirectoryReader, VectorIndex, LanguageModelPredictor, QueryHelper

from langchain.openai import LanguageModel

import gradio as gr

import os

# Set your OpenAI API key here to enable language model access

os.environ["OPENAI_API_KEY"] = 'your_openai_api_key'

def build_search_index(source_folder):

    input_limit = 2048

    response_length = 1024

    overlap_size = 30

    segment_limit = 500

    # Initialize helper to manage input and output configurations

    query_helper = QueryHelper(input_limit, response_length, overlap_size, segment_limit=segment_limit)

    # Set up the language model predictor with specified parameters

    model_predictor = LanguageModelPredictor(

        language_model=LanguageModel(temperature=0.7, model_name="text-davinci-003", max_tokens=response_length))

    # Load and process documents from the specified directory

    documents = DirectoryReader(source_folder).read_files()

    # Create an index with processed documents to facilitate search

    search_index = VectorIndex(documents, model_predictor=model_predictor, helper=query_helper)

    # Save the created index to the disk for later use

    search_index.persist('search_index.json')

    return search_index

def query_chatbot(user_input):

    # Load the pre-built index from the storage

    search_index = VectorIndex.load('search_index.json')

    # Generate a response based on the user input using the loaded index

    answer = search_index.search_query(user_input, mode="concise")

    return answer

# Setup the Gradio interface

interface = gr.Interface(

    fn=query_chatbot,

    inputs=gr.inputs.Textbox(lines=7, placeholder="Type your question here..."),

    outputs="text",

    title="Custom AI Assistant"

)

# Build index from the documents directory

index = build_search_index("path_to_documents")

# Launch the application with sharing options enabled

interface.launch(share=True)

Step 7: Run the Python script in the “Terminal”

Use the terminal to go to the directory where docs and app.py are located. Run the following command:

PYTHON3 APP.PY

Now, it will start to train your custom chatbot based on the data in your ‘docs’ folder. 

Depending on the amount of data you include, it might take some time. A local URL will be provided after training, where you can test the AI bot using a simple UI.

The AI bot will respond according to your added script when you ask questions.

Keep in mind that both training and asking questions will consume tokens.

All done now!

In Conclusion

Following the steps outlined in this article, you can start using your own data to control ChatGPT’s answers and create a unique conversational AI experience. 

Remember to get reliable data and successfully tweak your model. Always keep in mind the ethical factors when you train ChatGPT, and opt for a responsible attitude. 

There are enormous possibilities of combining ChatGPT and your own data, and you will see the innovative conversational AI chatbot you will create as a result.

Hope you start achieving your marketing goals by training ChatGPT on your own data!

Featured image by Solen Feyissa on Unsplash

The post A Marketer’s Guide to Training ChatGPT appeared first on noupe.

Categories: Others Tags:

Leading the Way to a Stress-Reduced Workplace

May 23rd, 2024 No comments

Today’s workplace can often feel demanding. Technology has made life easier in many ways, but it’s also created greater and faster expectations, leading to an increase in workplace stress. That stress impacts everyone in the working world, including leaders and their teams. 

Unfortunately, stress can wreak havoc on a workplace environment and the overall well-being of employees. Finding ways to reduce stress at work will not only benefit your team’s mental and physical health, but it will also help to boost team morale, productivity, and overall success. 

When you focus on stress reduction, you’ll create a work environment that people actually enjoy. That can help with longevity, retention, and recruitment later on. 

Finding stress-reduction solutions for the workplace doesn’t have to be a stressor, itself. By prioritizing some tips, techniques, and changes, you can create a happier, healthier workplace while reaping the benefits as a business. 

Why Is Stress So High? 

There are plenty of factors that can contribute to stress in the workplace. Some are professional, some are personal. The reality is that you never really know what’s going on in someone’s personal life that could be causing them to feel overwhelmed or anxious. When they come into a workplace environment that is stressful, chaotic, or toxic, they could end up burning out quickly. 

Not sure what could be causing low morale within your business? Some of the common factors include: 

  • Disconnection
  • Micromanagement
  • A lack of collaboration
  • Exclusivity
  • Lack of feedback

Employees who feel overworked and underappreciated are also more likely to be stressed. An overworked employee who isn’t being recognized is more likely to experience burnout. Unfortunately, that can create a sort of vicious cycle. The more burned out an employee feels, the less likely they are to feel passionate about their work. Productivity and morale will suffer, and so will your business.

Are you piling too much on your team? Are you looking over everyone’s shoulders more than you should? Take a look at your own potential stressor contributions to determine what should be changed first. 

How Stress Affects Your Business

Not only can the factors listed above create more stress, but they can end up causing low team morale. That leads to unhappy, unsatisfied employees, and a business that might end up struggling because no one is motivated to do their work. 

Too much stress in the workplace can also lead to human error. Mistakes and setbacks are bad for business, of course. But, more importantly, employees who are on the brink of burnout due to stress are more likely to make mistakes that could get them hurt. Stress management is essential for reducing the risk of workplace accidents. Too much stress can cause your team to become distracted, and it can lead to miscommunication and even increased absenteeism. The last thing you want is sick or injured employees because they’re under so much pressure.

Finally, you have to consider productivity. When you feel stressed, what do you accomplish? Probably not much. So, you can’t expect your team to meet deadlines or put out their best work when they’re feeling overwhelmed with stress. Pay attention to your employees and their workload and productivity. 

If you’re noticing things like a lack of energy or focus, constant worry, or reduced creativity, consider it a red flag. They might need less work, more flexibility, or different responsibilities. Keep in mind that stress from work could also be impacting their personal lives, creating negative changes to their personalities and disrupting their work-life balance. 

What Can You Do?

Recognizing that there’s a stress issue within your workplace is the first step toward making a cultural change within that environment. The next step is addressing the problems contributing to that stress. If you’re not sure how to address workplace stress, try implementing some of the following steps: 

  1. Provide education on stress management to employees
  2. Create and foster a supportive work environment
  3. Encourage open communication
  4. Promote a healthy work-life balance

Don’t hesitate to talk to your team about how they’re feeling and what their sources of stress might be. By making it a point to check in with everyone, individually, your employees are likely to feel more comfortable opening up. Not only will they share their struggles, but they might be able to give you actionable insight into what you can do to help. Some of the easiest ways to reduce stress in the workplace quickly include offering greater flexibility, promoting mental well-being, and providing workplace wellness programs. 

A wellness program can be very specific depending on the needs of your workplace. But, corporate wellness programs typically include things like fitness and health initiatives – including mental health. That might include insurance plans that cover therapy or counseling. You might even connect with local mental health organizations to provide resources to your employees when they’re needed. 

Again, consider asking your employees what would be most beneficial to their well-being. Some might suggest something as simple as more flexibility or more time off. Those are easy “fixes” that you can implement right away. While you might think more flexible schedules would lead to lower productivity, it’s usually the opposite that’s true. 

When your team is well-rested, happy, and they feel valued, they’re more likely to get more work done and take a lot of pride in what they’re doing. When you take those suggestions into account and actually include them as part of the program, your team will feel heard, understood, and appreciated. 

When you’re an advocate for a low-stress workplace, you will quickly gain a positive reputation in and out of the office for having a positive company culture. That can benefit your business and your bottom line more than you ever thought possible. A positive company culture can pave the way for increased job satisfaction, improved collaboration, a better company image, increased productivity, and, of course, reduced stress on employees. 

If you’re in a leadership role, consider it your responsibility to better understand the sources of stress in your workplace, so you can take quick and active steps toward reducing them. Your team will benefit, your business will benefit, and you’ll gain a positive reputation that can influence years of success and growth.

Featured image by Christina @ wocintechchat.com on Unsplash

The post Leading the Way to a Stress-Reduced Workplace appeared first on noupe.

Categories: Others Tags:

Modern CSS Layouts: You Might Not Need A Framework For That

May 22nd, 2024 No comments

Establishing layouts in CSS is something that we, as developers, often delegate to whatever framework we’re most comfortable using. And even though it’s possible to configure a framework to get just what we need out of it, how often have you integrated an entire CSS library simply for its layout features? I’m sure many of us have done it at some point, dating back to the days of 960.gs, Bootstrap, Susy, and Foundation.

Modern CSS features have significantly cut the need to reach for a framework simply for its layout. Yet, I continue to see it happen. Or, I empathize with many of my colleagues who find themselves re-creating the same Grid or Flexbox layout over and over again.

In this article, we will gain greater control over web layouts. Specifically, we will create four CSS classes that you will be able to take and use immediately on just about any project or place where you need a particular layout that can be configured to your needs.

While the concepts we cover are key, the real thing I want you to take away from this is the confidence to use CSS for those things we tend to avoid doing ourselves. Layouts used to be a challenge on the same level of styling form controls. Certain creative layouts may still be difficult to pull off, but the way CSS is designed today solves the burdens of the established layout patterns we’ve been outsourcing and re-creating for many years.

What We’re Making

We’re going to establish four CSS classes, each with a different layout approach. The idea is that if you need, say, a fluid layout based on Flexbox, you have it ready. The same goes for the three other classes we’re making.

And what exactly are these classes? Two of them are Flexbox layouts, and the other two are Grid layouts, each for a specific purpose. We’ll even extend the Grid layouts to leverage CSS Subgrid for when that’s needed.

Within those two groups of Flexbox and Grid layouts are two utility classes: one that auto-fills the available space — we’re calling these “fluid” layouts — and another where we have greater control over the columns and rows — we’re calling these “repeating” layouts.

Finally, we’ll integrate CSS Container Queries so that these layouts respond to their own size for responsive behavior rather than the size of the viewport. Where we’ll start, though, is organizing our work into Cascade Layers, which further allow you to control the level of specificity and prevent style conflicts with your own CSS.

Setup: Cascade Layers & CSS Variables

A technique that I’ve used a few times is to define Cascade Layers at the start of a stylesheet. I like this idea not only because it keeps styles neat and organized but also because we can influence the specificity of the styles in each layer by organizing the layers in a specific order. All of this makes the utility classes we’re making easier to maintain and integrate into your own work without running into specificity battles.

I think the following three layers are enough for this work:

@layer reset, theme, layout;

Notice the order because it really, really matters. The reset layer comes first, making it the least specific layer of the bunch. The layout layer comes in at the end, making it the most specific set of styles, giving them higher priority than the styles in the other two layers. If we add an unlayered style, that one would be added last and thus have the highest specificity.

Related: “Getting Started With Cascade Layers” by Stephanie Eckles.

Let’s briefly cover how we’ll use each layer in our work.

Reset Layer

The reset layer will contain styles for any user agent styles we want to “reset”. You can add your own resets here, or if you already have a reset in your project, you can safely move on without this particular layer. However, do remember that un-layered styles will be read last, so wrap them in this layer if needed.

I’m just going to drop in the popular box-sizing declaration that ensures all elements are sized consistently by the border-box in accordance with the CSS Box Model.

@layer reset {
  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }

  body {
    margin: 0;
  }
}

Theme Layer

This layer provides variables scoped to the :root element. I like the idea of scoping variables this high up the chain because layout containers — like the utility classes we’re creating — are often wrappers around lots of other elements, and a global scope ensures that the variables are available anywhere we need them. That said, it is possible to scope these locally to another element if you need to.

Now, whatever makes for “good” default values for the variables will absolutely depend on the project. I’m going to set these with particular values, but do not assume for a moment that you have to stick with them — this is very much a configurable system that you can adapt to your needs.

Here are the only three variables we need for all four layouts:

@layer theme {
  :root {
    --layout-fluid-min: 35ch;
    --layout-default-repeat: 3;
    --layout-default-gap: 3vmax;
  }
}

In order, these map to the following:

Notice: The variables are prefixed with layout-, which I’m using as an identifier for layout-specific values. This is my personal preference for structuring this work, but please choose a naming convention that fits your mental model — naming things can be hard!

Layout Layer

This layer will hold our utility class rulesets, which is where all the magic happens. For the grid, we will include a fifth class specifically for using CSS Subgrid within a grid container for those possible use cases.

@layer layout {  
  .repeating-grid {}
  .repeating-flex {}
  .fluid-grid {}
  .fluid-flex {}

  .subgrid-rows {}
}

Now that all our layers are organized, variables are set, and rulesets are defined, we can begin working on the layouts themselves. We will start with the “repeating” layouts, one based on CSS Grid and the other using Flexbox.

Repeating Grid And Flex Layouts

I think it’s a good idea to start with the “simplest” layout and scale up the complexity from there. So, we’ll tackle the “Repeating Grid” layout first as an introduction to the overarching technique we will be using for the other layouts.

Repeating Grid

If we head into the @layout layer, that’s where we’ll find the .repeating-grid ruleset, where we’ll write the styles for this specific layout. Essentially, we are setting this up as a grid container and applying the variables we created to it to establish layout columns and spacing between them.

.repeating-grid {
  display: grid;
  grid-template-columns: repeat(var(--layout-default-repeat), 1fr);
  gap: var(--layout-default-gap);
}

It’s not too complicated so far, right? We now have a grid container with three equally sized columns that take up one fraction (1fr) of the available space with a gap between them.

This is all fine and dandy, but we do want to take this a step further and turn this into a system where you can configure the number of columns and the size of the gap. I’m going to introduce two new variables scoped to this grid:

  • --_grid-repeat: The number of grid columns.
  • --_repeating-grid-gap: The amount of space between grid items.

Did you notice that I’ve prefixed these variables with an underscore? This was actually a JavaScript convention to specify variables that are “private” — or locally-scoped — before we had const and let to help with that. Feel free to rename these however you see fit, but I wanted to note that up-front in case you’re wondering why the underscore is there.

.repeating-grid {
  --_grid-repeat: var(--grid-repeat, var(--layout-default-repeat));
  --_repeating-grid-gap: var(--grid-gap, var(--layout-default-gap));

  display: grid;
  grid-template-columns: repeat(var(--layout-default-repeat), 1fr);
  gap: var(--layout-default-gap);
}

Notice: These variables are set to the variables in the @theme layer. I like the idea of assigning a global variable to a locally-scoped variable. This way, we get to leverage the default values we set in @theme but can easily override them without interfering anywhere else the global variables are used.

Now let’s put those variables to use on the style rules from before in the same .repeating-grid ruleset:

.repeating-grid {
  --_grid-repeat: var(--grid-repeat, var(--layout-default-repeat));
  --_repeating-grid-gap: var(--grid-gap, var(--layout-default-gap));

  display: grid;
  grid-template-columns: repeat(var(--_grid-repeat), 1fr);
  gap: var(--_repeating-grid-gap);
}

What happens from here when we apply the .repeating-grid to an element in HTML? Let’s imagine that we are working with the following simplified markup:

<section class="repeating-grid">
  <div></div>
  <div></div>
  <div></div>
</section>

If we were to apply a background-color and height to those divs, we would get a nice set of boxes that are placed into three equally-sized columns, where any divs that do not fit on the first row automatically wrap to the next row.

Time to put the process we established with the Repeating Grid layout to use in this Repeating Flex layout. This time, we jump straight to defining the private variables on the .repeating-flex ruleset in the @layout layer since we already know what we’re doing.

.repeating-flex {
  --_flex-repeat: var(--flex-repeat, var(--layout-default-repeat));
  --_repeating-flex-gap: var(--flex-gap, var(--layout-default-gap));
}

Again, we have two locally-scoped variables used to override the default values assigned to the globally-scoped variables. Now, we apply them to the style declarations.

.repeating-flex {
  --_flex-repeat: var(--flex-repeat, var(--layout-default-repeat));
  --_repeating-flex-gap: var(--flex-gap, var(--layout-default-gap));

  display: flex;
  flex-wrap: wrap;
  gap: var(--_repeating-flex-gap);
}

We’re only using one of the variables to set the gap size between flex items at the moment, but that will change in a bit. For now, the important thing to note is that we are using the flex-wrap property to tell Flexbox that it’s OK to let additional items in the layout wrap into multiple rows rather than trying to pack everything in a single row.

But once we do that, we also have to configure how the flex items shrink or expand based on whatever amount of available space is remaining. Let’s nest those styles inside the parent ruleset:

.repeating-flex {
  --_flex-repeat: var(--flex-repeat, var(--layout-default-repeat));
  --_repeating-flex-gap: var(--flex-gap, var(--layout-default-gap));

  display: flex;
  flex-wrap: wrap;
  gap: var(--_repeating-flex-gap);

  > * {
    flex: 1 1 calc((100% / var(--_flex-repeat)) - var(--_gap-repeater-calc));
  }
}

If you’re wondering why I’m using the universal selector (*), it’s because we can’t assume that the layout items will always be divs. Perhaps they are

elements,

s, or something else entirely. The child combinator (>) ensures that we’re only selecting elements that are direct children of the utility class to prevent leakage into other ancestor styles.

The flex shorthand property is one of those that’s been around for many years now but still seems to mystify many of us. Before we unpack it, did you also notice that we have a new locally-scoped --_gap-repeater-calc variable that needs to be defined? Let’s do this:

.repeating-flex {
  --_flex-repeat: var(--flex-repeat, var(--layout-default-repeat));
  --_repeating-flex-gap: var(--flex-gap, var(--layout-default-gap));

  /* New variables */
  --_gap-count: calc(var(--_flex-repeat) - 1);
  --_gap-repeater-calc: calc(
    var(--_repeating-flex-gap) / var(--_flex-repeat) * var(--_gap-count)
  );

  display: flex;
  flex-wrap: wrap;
  gap: var(--_repeating-flex-gap);

  > * {
    flex: 1 1 calc((100% / var(--_flex-repeat)) - var(--_gap-repeater-calc));
  }
}

Whoa, we actually created a second variable that --_gap-repeater-calc can use to properly calculate the third flex value, which corresponds to the flex-basis property, i.e., the “ideal” size we want the flex items to be.

If we take out the variable abstractions from our code above, then this is what we’re looking at:

.repeating-flex {
  display: flex;
  flex-wrap: wrap;
  gap: 3vmax

  > * {
    flex: 1 1 calc((100% / 3) - calc(3vmax / 3 * 2));
  }
}

Hopefully, this will help you see what sort of math the browser has to do to size the flexible items in the layout. Of course, those values change if the variables’ values change. But, in short, elements that are direct children of the .repeating-flex utility class are allowed to grow (flex-grow: 1) and shrink (flex-shrink: 1) based on the amount of available space while we inform the browser that the initial size (i.e., flex-basis) of each flex item is equal to some calc()-ulated value.

Because we had to introduce a couple of new variables to get here, I’d like to at least explain what they do:

  • --_gap-count: This stores the number of gaps between layout items by subtracting 1 from --_flex-repeat. There’s one less gap in the number of items because there’s no gap before the first item or after the last item.
  • --_gap-repeater-calc: This calculates the total gap size based on the individual item’s gap size and the total number of gaps between items.

From there, we calculate the total gap size more efficiently with the following formula:

calc(var(--_repeating-flex-gap) / var(--_flex-repeat) * var(--_gap-count))

Let’s break that down further because it’s an inception of variables referencing other variables. In this example, we already provided our repeat-counting private variable, which falls back to the default repeater by setting the --layout-default-repeat variable.

This sets a gap, but we’re not done yet because, with flexible containers, we need to define the flex behavior of the container’s direct children so that they grow (flex-grow: 1), shrink (flex-shrink: 1), and with a flex-basis value that is calculated by multiplying the repeater by the total number of gaps between items.

Next, we divide the individual gap size (--_repeating-flex-gap) by the number of repetitions (--_flex-repeat)) to equally distribute the gap size between each item in the layout. Then, we multiply that gap size value by one minus the total number of gaps with the --_gap-count variable.

And that concludes our repeating grids! Pretty fun, or at least interesting, right? I like a bit of math.

Before we move to the final two layout utility classes we’re making, you might be wondering why we want so many abstractions of the same variable, as we start with one globally-scoped variable referenced by a locally-scoped variable which, in turn, can be referenced and overridden again by yet another variable that is locally scoped to another ruleset. We could simply work with the global variable the whole time, but I’ve taken us through the extra steps of abstraction.

I like it this way because of the following:

  1. I can peek at the HTML and instantly see which layout approach is in use: .repeating-grid or .repeating-flex.
  2. It maintains a certain separation of concerns that keeps styles in order without running into specificity conflicts.

See how clear and understandable the markup is:

<section class="repeating-flex footer-usps">
  <div></div>
  <div></div>
  <div></div>
</section>

The corresponding CSS is likely to be a slim ruleset for the semantic .footer-usps class that simply updates variable values:

.footer-usps {
  --flex-repeat: 3;
  --flex-gap: 2rem;
}

This gives me all of the context I need: the type of layout, what it is used for, and where to find the variables. I think that’s handy, but you certainly could get by without the added abstractions if you’re looking to streamline things a bit.

Fluid Grid And Flex Layouts

All the repeating we’ve done until now is fun, and we can manipulate the number of repeats with container queries and media queries. But rather than repeating columns manually, let’s make the browser do the work for us with fluid layouts that automatically fill whatever empty space is available in the layout container. We may sacrifice a small amount of control with these two utilities, but we get to leverage the browser’s ability to “intelligently” place layout items with a few CSS hints.

Fluid Grid

Once again, we’re starting with the variables and working our way to the calculations and style rules. Specifically, we’re defining a variable called --_fluid-grid-min that manages a column’s minimum width.

Let’s take a rather trivial example and say we want a grid column that’s at least 400px wide with a 20px gap. In this situation, we’re essentially working with a two-column grid when the container is greater than 820px wide. If the container is narrower than 820px, the column stretches out to the container’s full width.

If we want to go for a three-column grid instead, the container’s width should be about 1240px wide. It’s all about controlling the minimum sizing values in the gap.

.fluid-grid {
  --_fluid-grid-min: var(--fluid-grid-min, var(--layout-fluid-min));
  --_fluid-grid-gap: var(--grid-gap, var(--layout-default-gap));
}

That establishes the variables we need to calculate and set styles on the .fluid-grid layout. This is the full code we are unpacking:

 .fluid-grid {
  --_fluid-grid-min: var(--fluid-grid-min, var(--layout-fluid-min));
  --_fluid-grid-gap: var(--grid-gap, var(--layout-default-gap));

  display: grid;
  grid-template-columns: repeat(
    auto-fit,
    minmax(min(var(--_fluid-grid-min), 100%), 1fr)
  );
  gap: var(--_fluid-grid-gap);
}

The display is set to grid, and the gap between items is based on the --fluid-grid-gap variable. The magic is taking place in the grid-template-columns declaration.

This grid uses the repeat() function just as the .repeating-grid utility does. By declaring auto-fit in the function, the browser automatically packs in as many columns as it possibly can in the amount of available space in the layout container. Any columns that can’t fit on a line simply wrap to the next line and occupy the full space that is available there.

Then there’s the minmax() function for setting the minimum and maximum width of the columns. What’s special here is that we’re nesting yet another function, min(), within minmax() (which, remember, is nested in the repeat() function). This a bit of extra logic that sets the minimum width value of each column somewhere in a range between --_fluid-grid-min and 100%, where 100% is a fallback for when --_fluid-grid-min is undefined or is less than 100%. In other words, each column is at least the full 100% width of the grid container.

The “max” half of minmax() is set to 1fr to ensure that each column grows proportionally and maintains equally sized columns.

See the Pen Fluid grid [forked] by utilitybend.

That’s it for the Fluid Grid layout! That said, please do take note that this is a strong grid, particularly when it is combined with modern relative units, e.g. ch, as it produces a grid that only scales from one column to multiple columns based on the size of the content.

Fluid Flex

We pretty much get to re-use all of the code we wrote for the Repeating Flex layout for the Fluid Flex layout, but only we’re setting the flex-basis of each column by its minimum size rather than the number of columns.

.fluid-flex {
  --_fluid-flex-min: var(--fluid-flex-min, var(--layout-fluid-min));
  --_fluid-flex-gap: var(--flex-gap, var(--layout-default-gap));

  display: flex;
  flex-wrap: wrap;
  gap: var(--_fluid-flex-gap);

  > * {
    flex: 1 1 var(--_fluid-flex-min);
  }
}

That completes the fourth and final layout utility — but there’s one bonus class we can create to use together with the Repeating Grid and Fluid Grid utilities for even more control over each layout.

Optional: Subgrid Utility

Subgrid is handy because it turns any grid item into a grid container of its own that shares the parent container’s track sizing to keep the two containers aligned without having to redefine tracks by hand. It’s got full browser support and makes our layout system just that much more robust. That’s why we can set it up as a utility to use with the Repeating Grid and Fluid Grid layouts if we need any of the layout items to be grid containers for laying out any child elements they contain.

Here we go:

.subgrid-rows {
  > * {
    display: grid;
    gap: var(--subgrid-gap, 0);
    grid-row: auto / span var(--subgrid-rows, 4);
    grid-template-rows: subgrid;
  }
}

We have two new variables, of course:

  • --subgrid-gap: The vertical gap between grid items.
  • --subgrid-rows The number of grid rows defaulted to 4.

We have a bit of a challenge: How do we control the subgrid items in the rows? I see two possible methods.

Method 1: Inline Styles

We already have a variable that can technically be used directly in the HTML as an inline style:

<section class="fluid-grid subgrid-rows" style="--subgrid-rows: 4;">
  <!-- items -->
</section>

This works like a charm since the variable informs the subgrid how much it can grow.

Method 2: Using The :has() Pseudo-Class

This approach leads to verbose CSS, but sacrificing brevity allows us to automate the layout so it handles practically anything we throw at it without having to update an inline style in the markup.

Check this out:

.subgrid-rows {
  &:has(> :nth-child(1):last-child) { --subgrid-rows: 1; }
  &:has(> :nth-child(2):last-child) { --subgrid-rows: 2; }
  &:has(> :nth-child(3):last-child) { --subgrid-rows: 3; }
  &:has(> :nth-child(4):last-child) { --subgrid-rows: 4; }
  &:has(> :nth-child(5):last-child) { --subgrid-rows: 5; }
  /* etc. */

  > * {
    display: grid;
    gap: var(--subgrid-gap, 0);
    grid-row: auto / span var(--subgrid-rows, 5);
    grid-template-rows: subgrid;
  }
}

The :has() selector checks if a subgrid row is the last child item in the container when that item is either the first, second, third, fourth, fifth, and so on item. For example, the second declaration:

&:has(> :nth-child(2):last-child) { --subgrid-rows: 2; }

…is pretty much saying, “If this is the second subgrid item and it happens to be the last item in the container, then set the number of rows to 2.”

Whether this is too heavy-handed, I don’t know; but I love that we’re able to do it in CSS.

The final missing piece is to declare a container on our children. Let’s give the columns a general class name, .grid-item, that we can override if we need to while setting each one as a container we can query for the sake of updating its layout when it is a certain size (as opposed to responding to the viewport’s size in a media query).

:is(.fluid-grid:not(.subgrid-rows),
.repeating-grid:not(.subgrid-rows),
.repeating-flex, .fluid-flex) {
    > * {
    container: var(--grid-item-container, grid-item) / inline-size;
  }
}

That’s a wild-looking selector, but the verbosity is certainly kept to a minimum thanks to the :is() pseudo-class, which saves us from having to write this as a larger chain selector. It essentially selects the direct children of the other utilities without leaking into .subgrid-rows and inadvertently selecting its direct children.

The container property is a shorthand that combines container-name and container-type into a single declaration separated by a forward slash (/). The name of the container is set to one of our variables, and the type is always its inline-size (i.e., width in a horizontal writing mode).

The container-type property can only be applied to grid containers — not grid items. This means we’re unable to combine it with the grid-template-rows: subgrid value, which is why we needed to write a more complex selector to exclude those instances.

Demo

Check out the following demo to see how everything comes together.

See the Pen Grid system playground [forked] by utilitybend.

The demo is pulling in styles from another pen that contains the full CSS for everything we made together in this article. So, if you were to replace the .fluid-flex classname from the parent container in the HTML with another one of the layout utilities, the layout will update accordingly, allowing you to compare them.

Those classes are the following:

  • .repeating-grid,
  • .repeating-flex,
  • .fluid-grid,
  • .fluid-flex.

And, of course, you have the option of turning any grid items into grid containers using the optional .subgrid-rows class in combination with the .repeating-grid and .fluid-grid utilities.

Conclusion: Write Once And Repurpose

This was quite a journey, wasn’t it? It might seem like a lot of information, but we made something that we only need to write once and can use practically anywhere we need a certain type of layout using modern CSS approaches. I strongly believe these utilities can not only help you in a bunch of your work but also cut any reliance on CSS frameworks that you may be using simply for its layout configurations.

This is a combination of many techniques I’ve seen, one of them being a presentation Stephanie Eckles gave at CSS Day 2023. I love it when people handcraft modern CSS solutions for things we used to work around. Stephanie’s demonstration was clean from the start, which is refreshing as so many other areas of web development are becoming ever more complex.

After learning a bunch from CSS Day 2023, I played with Subgrid on my own and published different ideas from my experiments. That’s all it took for me to realize how extensible modern CSS layout approaches are and inspired me to create a set of utilities I could rely on, perhaps for a long time.

By no means am I trying to convince you or anyone else that these utilities are perfect and should be used everywhere or even that they’re better than . One thing that I do know for certain is that by experimenting with the ideas we covered in this article, you will get a solid feel of how CSS is capable of making layout work much more convenient and robust than ever.

Create something out of this, and share it in the comments if you’re willing — I’m looking forward to seeing some fresh ideas!

Categories: Others Tags:

Top Web Hosting Features Every E-commerce Store Needs 

May 22nd, 2024 No comments

E-commerce is a competitive biz, so when you find small things you can do to make a big difference, you have nothing to lose by doing them. Like making sure your online store has all the top web hosting features every e-commerce feature needs, to make life easier for your visitors and get those sales ticking over. 

E-Commerce Hosting: What Is It? 

E-commerce hosting is web hosting services specifically tailored for businesses selling products or services on the internet. These kinds of web hosts offer handy features for selling, like website/storefront builders, shopping cart software, payment gateways, and on-the-ball customer support who are knowledgeable about online stores. 

Why Hosting Matters for E-Commerce Success

Your web hosting affects everything from your website’s security to user experience. With a good web host on your side, you can look forward to faster page loading times, which lowers customer frustration and minimizes cart abandonment. 

Then there’s the extra security, which builds trust and protects your customer’s info. A good web host will also be able to handle spikes in website traffic, keeping your store up and running even if there’s a bit of a surge. 

Key Features to Look for in E-Commerce Web Hosting 

Find a web host that ticks all the boxes. Here are the top web hosting features every e-commerce store needs. Make sure your host has them all! 

1. High Uptime Guarantee

You can’t make sales if your store is down. If you’re serious about your business, find a web host that has an uptime guarantee of 99.99% or higher. This means your store will almost always be online, with no risk of someone trying to shop while your site is down. Plus, research shows that if someone tries to access your site while it’s down, their trust in you goes down. 

2. Scalability

As your business grows, your hosting needs will probably change. From the start, choose a hosting provider that offers scalable solutions. This allows you to upgrade your resources easily and seamlessly without having a negative effect on your site’s performance. 

Scalability is super important in handling traffic spikes during peak shopping times, especially during holidays or sales events. A scalable hosting solution is like opening your doors wider—it can allow a larger number of visitors and transactions without crashing. 

3. Speed and Performance

Once your visitors have arrived on your site, keep them there with fast page loading times. Your web host should make it their mission to be fast and perform seamlessly. Look for features like SSD storage, using content delivery services (CDNs), and regular updates. 

Don’t neglect this! A faster site boosts the user’s experience, reducing bounce rate and increasing conversions. Plus, it helps you climb those elusive SEO rankings, so it’s double important! 

4. Security Features

Protecting your customers’ data is one of the most important things you can do. Make sure your hosting provider offers excellent security features, such as SSL certificates, regular malware scans, firewalls, and DDoS protection. 

This doesn’t just protect your customers’ data. It also keeps you safe from cyber threats and builds trust in your customer community. 

5. E-Commerce Integration 

If you’re selling, you need e-commerce features. Your host should make it easy for you to link up to popular e-commerce platforms like Shopify, Magento, WooCommerce, and others. 

These features usually help you to do things like process orders more efficiently, keep track of your stock, and provide decent customer service. 

6. Backup and Restore Options 

If your store crashes, will it be a quick process to get it back up and running? Your hosting provider needs to offer automatic backups and restorations, or they’re not worth your money! 

Accidents happen, and trust us—even fast restoring options can feel like they take forever. And every minute your website isn’t available is a minute you’re losing out on sales. 

Don’t leave room for potential problems—just choose a web host that’s meticulous about backing up your data and offers easy-restore features. 

7. Easy-to-Use Control Panel

Managing your hosting shouldn’t be difficult. A user-friendly control panel, like cPanel or Plesk, makes it easier to handle things like setting up email accounts, managing domains, and setting up your server settings. 

Even if you’ve got the tech know-how, a simple, easy control panel makes life easier. You can focus more on just running your business and less on the server admin side of things! 

8. SEO Tools and Features 

Surprisingly, good web hosting can improve your site’s search engine rankings on Google. Better SEO = better rankings, so choose a host with things like site analytics and SEO plugins to take advantage of this. 

Better SEO leads to more organic traffic, more potential customers, and at the end of the day, more sales. Built-in SEO tools mean you don’t need to clutter up your dashboard with plugins. 

9. Analytics and Reporting 

Don’t think keeping track of your site’s performance is silly. Find a host that gives you data on visitor behavior, where your traffic comes from, and sales figures. Study it. Use it to make better business decisions. 

10. Customer Support 

You never know when you might need extra support. Traveling to a different time zone? Struggling to sleep? Choose a host with 24/7 customer support so you can always reach out when you need to. 

Conclusion 

Putting together an effective, popular, and successful e-commerce store isn’t hard, especially if you know what features are important. Does your business have all these top web hosting features every e-commerce store needs? Now’s the time to make changes to start ticking these boxes… Your sales (and business success) depend on you!

Featured Image by storyset on Freepik

The post Top Web Hosting Features Every E-commerce Store Needs  appeared first on noupe.

Categories: Others Tags:

Best PDF Invoice and Document Generation Plugins

May 21st, 2024 No comments

In this blog, we’ll explore a selection of top-notch plugins designed to simplify your invoicing and document creation processes. Whether you’re running a WooCommerce store, managing orders in WordPress, or seeking versatile solutions for generating professional invoices and documents, these plugins have got you covered. 

Why businesses might need PDF invoice and document generation plugins?

PDF invoice and document generation plugins are invaluable tools for businesses and individuals looking to simplify their invoicing and document creation processes. The ability to generate professional-looking invoices, packing slips, delivery notes, and other documents efficiently is essential for maintaining a polished and organized image. 

These plugins offer a range of benefits, including saving time by automating the creation of documents, improving professionalism with branded templates, and enhancing organization by centralizing document management.

With the help of PDF invoice and document generation plugins, businesses can simplify their workflow, impress clients with polished documents, and ensure smoother operations overall.

Best PDF Invoice and Document Generation Plugins to Consider

Let’s dive in and discover the top plugins that can enhance your business efficiency.

1- WooCommerce PDF Invoices, Packing Slips and Credit Notes

With the WooCommerce PDF Invoices plugin, generating professional invoices, packing slips, and credit notes has never been easier. 

With this user-friendly plugin, you can automate the generation of PDF documents for invoices, packing slips, and credit notes. It allows you to attach these documents to order emails and customize templates to match your brand. 

You can also easily download or print invoices and packing slips, choose custom numbering for documents, and even offer a “pay later” option for customers. These features enhance your store’s functionality and contribute to a smoother and more professional customer experience.

By simplifying the invoicing process and providing advanced customization options, this plugin helps you save time and maintain a professional image for your business. 

2- PDF Invoices & Packing Slips for WooCommerce by WP Overnight

The PDF Invoices & Packing Slips plugin by WP Overnight is an essential extension that seamlessly integrates into your store. It automatically adds PDF or UBL invoices to order confirmation emails sent to your valued customers.

With a basic template included and the option to customize or create your own templates, you can ensure that your invoices and packing slips reflect your brand’s identity perfectly. You can even attach invoices to WooCommerce emails of your choice and can also download or print documents directly from the WooCommerce order admin page. This will simplify your order management process.

Furthermore, the plugin offers bulk PDF generation, fully customizable HTML/CSS invoice templates, and multi-language support. With its sequential invoice numbers and custom formatting options, you will also have complete control over the numbering of your invoices. 

Overall, you can simplify your order management process, enhance your brand’s image, and elevate the customer experience with this indispensable tool for WooCommerce store owners.

3- WooCommerce Shipping Labels, Dispatch Labels and Delivery Notes

WooCommerce Shipping Labels plugin is a comprehensive plugin designed to simplify your order processing by creating professional dispatch labels, shipping labels, and delivery notes for WooCommerce orders. With custom settings and layouts tailored to your business, this plugin simplifies the generation of essential order documents.

It automatically generates fully customized documents. It offers multiple pre-built layouts to choose from. It also allows you to create your own templates by adding, removing, or editing components of the document layouts to suit your business requirements. 

The generated documents can be easily accessed from the order edit page of each order. You can add a ‘Print’ button to order status emails for convenient printing directly from the email. You can also easily add multiple labels to a single page and bulk-print them directly from the admin order page for efficient order processing.

It even allows you to add additional order and product-related information, such as meta fields and product attributes, to your WooCommerce documents. Plus, it offers seamless multilingual support. Overall, this plugin is a great option for simplifying your order processing.

4- Sliced Invoices

Sliced Invoices is a user-friendly WordPress invoicing plugin that simplifies your quoting and invoicing processes. With Sliced Invoices, creating professional quotes and invoices that clients can pay for online has always been easier. 

The plugin offers many customization options, including pre-defined line items, customizable email templates, and flexible tax settings. You can also personalize your invoices with your logo and business details, ensuring a polished presentation. 

Plus, with features like automatic increment of invoice and quote numbers, customizable templates using CSS, and support for bulk CSV import of quotes and invoices, Sliced Invoices empowers you to manage your invoicing efficiently and effectively.

The plugin also offers features like sending automatic payment reminder emails and cloning existing quotes and invoices, further enhancing your invoicing workflow. Whether you’re a freelancer, small business owner, or agency, Sliced Invoices provides the flexibility and support you need to create professional quotes and invoices with ease.

5- PeproDev Ultimate Invoice

PeproDev Ultimate Invoice is a great solution for generating advanced HTML/PDF invoices for WooCommerce orders. This plugin offers unparalleled customization options, allowing you to create beautiful, professional-looking invoices that perfectly reflect your brand identity.

With PeproDev Ultimate Invoice, you can effortlessly download PDF invoices, email-styled invoices, and attach PDF invoices to WooCommerce emails, packing slips, shipping labels, and shipping tracking. You can provide them with downloadable, customizable styled invoices that meet their expectations.

The plugin offers full customization capabilities. You can customize every aspect of your invoices, from the layout to the design, and even create your own invoice templates, PDF invoice templates, inventory report templates, and packing slip templates. You can also alter plugins via Action/Filter hooks.

With PeproDev Ultimate Invoice, you can simplify your invoicing process and elevate your WooCommerce store 

6- WooCommerce Proforma Invoices Plugin

The WooCommerce Proforma Invoices Plugin is an advanced tool designed to simplify the creation of custom proforma invoices for all orders in your WooCommerce store. With this plugin, you can effortlessly generate branded proforma invoices that align with your business standards, complete with advanced settings and layout customizations.

It allows you to automatically generate proforma invoices for all orders in your store and easily customize them by adjusting plugin configurations to suit your needs. You can also customize pre-built layouts by adding, removing, or editing components.

It offers custom numbering options to personalize proforma invoice numbers. You can adjust starting numbers, number formats, and lengths to your preference. You can also add custom fields such as special notes, transport terms, sales terms, and custom footers. 

These WooCommerce proforma invoice PDFs can be attached to order emails, along with specific order status emails for attachment. Customers can also print invoices directly from the ‘My accounts’ page of your store, either individually or in bulk.

Plus, it offers seamless multilingual support. overall, you can simplify your invoicing process and elevate your business standards with the WooCommerce Proforma Invoices Plugin.

7- WooCommerce PDF Invoice Builder by RedNao

WooCommerce PDF Invoice Builder by RedNao is an innovative plugin that revolutionizes PDF creation for your WooCommerce store. With its intuitive drag-and-drop builder, you can effortlessly create invoices, packing slips, credit notes, and more. 

The plugin allows you to easily customize fields such as dates, invoice numbers, and billing addresses, and personalize detail tables with different colors, styles, and columns. Plus, it offers over 500 icons, image support, and style designer, with which you can make your PDF invoice unique and professional.

You can download your PDFs directly from your dashboard or configure them to be sent within WooCommerce emails. It also offers a variety of PDF templates to choose from if you’re short on time. The plugin automatically formats amounts using the currency of the order. 

Also, with configurable invoice numbers and file names, WooCommerce PDF Invoice Builder by RedNao offers unparalleled flexibility and convenience for your invoicing needs.

8- Challan

Challan is a comprehensive PDF Invoice & Packing Slip plugin for WooCommerce that simplifies your invoicing process effortlessly. With Challan, you can automatically generate PDF invoices and packing slips, attaching them to order confirmation emails based on the configured order status. 

Its intuitive drag-and-drop builder makes creating and printing invoices a breeze. From resizing PDFs to bulk downloading invoices and packing slips, Challan simplifies the sales and purchasing process.

Its customization options ensure your documents reflect your brand’s identity perfectly. Challan allows you to set shipping and billing information, order data, customer notes, tax details, and more with ease. You can also customize invoice numbers, order titles, product details, and templates effortlessly, and tailor the invoice style using custom CSS. 

Plus, with features like automatic attachment of invoices and packing slips to order confirmation emails, delivery address generation, and sequential order numbering, Challan empowers you to create professional and organized invoices and packing slips for your WooCommerce store.

9- Flexible PDF Invoices for WooCommerce & WordPress

Flexible PDF Invoices for WooCommerce & WordPress is a versatile plugin that empowers you to create invoices effortlessly, whether for WooCommerce orders or standalone transactions within WordPress. With this plugin, you can issue VAT invoices seamlessly, simplifying your invoicing process across all platforms.

The free version of Flexible PDF Invoices offers a range of powerful features, including the ability to issue PDF invoices for WooCommerce orders and manually create VAT invoices in both WooCommerce and WordPress. 

The plugin allows you to easily manage invoices as custom post types, add, edit, and delete invoices with ease, and send them manually as needed. You can also customize your PDF invoice templates to suit VAT taxpayers and VAT-exempt entities and generate and download invoices in bulk by date range for efficient invoicing. 

Plus, with options to add payment info, additional notes, and custom numbering of invoices, Flexible PDF Invoices provides the flexibility and convenience you need to manage your invoicing efficiently.

10- Print Invoice & Delivery Notes for WooCommerce

Print Invoice & Delivery Notes for WooCommerce is yet another powerful tool that simplifies the process of printing invoices and delivery notes for WooCommerce orders. With this plugin, you can effortlessly print out invoices and delivery notes, customize them with your company or shop details, and even add personal notes, conditions, or policies.

The plugin seamlessly integrates into your WooCommerce order management system, adding a convenient side panel for administrators on the order edit page. This allows you to print invoices or delivery notes quickly. 

Additionally, registered customers can easily print their orders with a button added to the order screen. It also offers features like bulk printing, allows customers to print orders from their account page, and includes print links in customer emails for added convenience.

With support for simple and sequential invoice numbering, as well as compatibility with the WooCommerce refund system, this plugin offers flexibility and functionality to meet your invoicing needs.

Conclusion

Investing in PDF invoice and document generation plugins can revolutionize how businesses manage invoicing and document creation processes. 

With the ability to automate tasks, improve professionalism, and enhance organization, these plugins offer invaluable solutions for managing operations and impressing clients. Whether you’re a small business owner or a seasoned professional, integrating these plugins into your workflow can lead to significant time savings and improved efficiency.

Featured image by FIN on Unsplash

The post Best PDF Invoice and Document Generation Plugins appeared first on noupe.

Categories: Others Tags: