v

22 passive income ideas to achieve financial freedom

Earn while you sleep: Realistic passive income ideas you can pursue part time! Ditch the 9-5 with the right idea, hard work, & these essential tools.




v

How to hire a WooCommerce developer

Hire a WooCommerce developer who's reliable, affordable, & gets the job done on time. 4 ways to find the right fit. Here’s what to ask first.




v

Unique value proposition — Why it matters and how to write one 

What makes consumers choose one company over another? Identify your unique value proposition to make more sales at higher prices. Examples & tips.




v

WooCommerce stores are revving up for Black Friday: The 2024 holiday trends survey

As ecommerce revs up for the holidays, it's time to prepare. Brand new survey data for Black Friday 2024 stats and trends from your friends at Woo.




v

Top Life Project surpasses revenue goals by 59% in year one

How did Top Life Project exceed revenue goals by 59%? The story behind their WooCommerce-powered health brand & booming product launches.




v

Competitive analysis — What to do before you commit to your next great business idea

Planning a new online business? Conduct a competitive analysis to understand your market, beat your rivals, and position your brand for success.




v

First time of Starboard Waterline SUP on Horsetooth Reservoir

In mid-June, I went paddleboarding on Horsetooth Reservoir, starting from Soldier Cove in Lory State Park. I believe it is the shortest walk from the park to the water and puts you in the middle of somewhat protected and quiet […]




v

Summer paddling, swimming and photography on Horsetooth Reservoir

Stand up paddling During August 2023 I visited Horsetooth Reservoir several times with Starboard Waterline SUP, the same board I paddled in the Missouri River 340 race. It was rather a relaxed paddling with a lot of photography since I […]













v

Biodiversity Isn’t Just Pretty: It Future-Proofs Our World

By Elizabeth Boakes Aeon A small boy hauls enthusiastically on his fishing rod. The line flies up and a needle-spined fish strikes him in the eye. Desperate to stay outdoors, he ignores the pain, but his sight deteriorates over the … Continue reading





v

How Generative AI Can Add Human Delight to Your Virtual Event

We just celebrated 24 years of Viget. That’s two dozen years! This year, our Spring TTT in celebration of “Viget24” was a virtual extravaganza. We’ve put on a lot of virtual events over the years. Some with really strong themes and swag bags; some that focus on simple, meaningful time together; and others that let us enjoy learning something new as a team. Regardless of the rest of the experience, a key component of all of our virtual events is joyachieved often through intentional levity. We think it’s important to laugh together! We see laughter as a way to expedite connection, and connection leads to rapport which makes us better at collaborating — and in turn leads to more quality products for our clients. 

Experimenting and iterating is a critical way we try to continually get delight right. We’re pretty pleased with one of our experiments from Viget24 that we called “Lovely Spring Day”.

A Lovely Spring Day

As we were brainstorming for this TTT, we thought about how to throw some joyful levity pizzazz into the pieces of our virtual events puzzle that have become pretty standard. How do we add lots of delight without adding lots of time to the action-packed schedule? We zeroed in on the virtual backgrounds we’ve been creating for every event — they add a layer of specialness. Of place. This isn’t any old virtual meeting. This is a TTT! 

A small collection of past event-specific virtual backgrounds

Another key consideration for our team is figuring out creative ways to tie in inspiration from our industry and our work. AI has been an obvious contender —  we’ve discussed it and tied it in to some extent for the past several TTTs. But this time, we wanted to see how we could use AI for delight — marrying it with virtual backgrounds felt obvious. And so, a ”Lovely Spring Day” was born. 

The TL;DR is that we generated custom virtual backgrounds for every Viget employee that encapsulates their “ideal spring day.” We then played a 15-minute guessing game where people tried to guess who the background “belonged to.” Then, people had access to the full folder of AI-generated virtual backgrounds to look through. Vigets could then choose the background that spoke to them most and set it as their background. 

Read on for more on how we put this together!

Pre-Event Survey

To support all of our TTTs, we send out thoughtful pre-event logistics surveys 2-3 weeks before the big day. The survey lets us know where folks are joining from (where can we send their activity + snack packages?) and gives folks a chance to provide input on how the People Team can help folks enjoy and be present for TTT. This time, we also snuck in three questions, just “for giggles.”

  • In one sentence, describe your ideal spring day.
  • List three things that spark joy.
  • What color do you think suits you best?

We did not share why we asked these questions. Sneaky, sneaky! When it’s low-key like this, the element of surprise is often a quick way to level up the delight.

Asking for a Friend

With rich data in hand about what makes people happy in spring, we were ready to generate the backgrounds. I was stoked! I’ve been experimenting with ChatGPT for some time, so it was fun to be able to use the DALL-E 3 side of OpenAI’s GPT-4 model

Who knew Prompt Engineering would be part of my role as a recruiter-who-helps-support-TTT-planning? I played around with a couple different prompts to generate these background images. Ultimately, my goal was to create backgrounds that were meaningfully different from one another but still felt good (i.e., something you might feasibly want to set as your virtual background and nothing freakily AI, like uncanny valley hands).

Here are the prompts I landed on that got me to our set of virtual backgrounds:

  • Please generate an image (dimensions of a virtual meeting background) that encapsulates the vibe of a day with [ BLANK ].
  • Please generate an image (dimensions of a virtual meeting background) that features [ BLANK ].

In the blanks, I wrote the things people included in their surveys. Those blanks were filled with everything ranging from dogs, cats, and friends to beverages, specific temperatures, yard games, carbohydrates, hammocks and more! Sometimes, I’d include a detail I knew about that person myself, even if it wasn’t in their survey. Yes, I occasionally editorialized for both clarity and whimsy! This was for delight purposes, but also helped serve my goal of having the backgrounds be “meaningfully different from one another.” It’s amazing how many people’s ideal spring day is as simple as having 1) moderate temperatures and 2) no pollen!

I generated 55 images. Throughout the process, DALL-E nailed it. I only needed to regenerate 2 or 3 images with clarifiers (and only because they included AI-specific outliers like disembodied hands). Huzzah!

Here are some of my favorites, along with their prompts in the captions. Can you guess who they belong to?

Please generate an image (dimensions of a virtual meeting background) that features an outdoor brewery/taproom in the appalachian mountains. There's a playground with kids in the very distance. In the foreground, frisbee, soccer, volleyball, etc. with friends and family.
Please generate an image that encapsulates the vibe of a day ending with an outdoor dinner with lights near an outdoor shower. There should be some hiking boots scattered about.
Please generate an image that features a nice hot bath after a cold but sunny day, with a beautiful mug of green tea and a box of takeout that looks really good. The calendar shows April 25th.
Please generate an image that encapsulates the vibe of sitting outside in a nice purple adirondack chair with buc-ees paraphernalia around.
Please generate an image that encapsulates the vibe of a sunny, 65 degree day with a slight breeze at the ballpark watching a game. The image should feature cats, baseball, and art.
Please generate an image that encapsulates the vibe of being outside in a canoe along with carbs, bad jokes, and games (video OR board games).
Please generate an image that features endless mountain bike trails, a blue bike with a cup of coffee in the cupholder, and roaming cats.

IRL

Ok, so for the actual activity we had the images ready to go in a private Google Folder. I took twelve of the images and put them in a very simple deck. I shared my screen, introduced the activity, and invited people to guess who they think each image belonged to in Slack. It was so fun seeing people throw out guesses and then narrow in with any verbal hints I gave!

Each image took about a minute. Then, we shared access to the Google Folder, gave folks a couple minutes to choose a background that called to them (their own image or someone else’s), and set it as their background. It felt like a magical moment to witness people finding and resonating with their own image or delighting in the ridiculousness of their coworkers’. We saved about 5 minutes for this piece, which felt right.

The whole Lovely Spring Day activity took just over 15 minutes! It was a perfect way to transition from a long meal break into our next grouping of content. And, we got to see the different backgrounds throughout the rest of the meeting.

Oh, the humanity!

I think this activity was successful for a couple of reasons.

1. People laughed! 

Color commentary in the #ttt Slack channel

2. People felt seen. Some of these backgrounds were incredibly on point. Some of that was due to key folks having well-documented interests and a Slack-Famous Dog. 

Laura Sweltz has a famous love of books and an incredibly iconic beagle named Phoebe.

But some of it was due to the People Team knowing about our people — our coworkers — beyond the sentence they wrote in. This uniquely human involvement helped me call an audible as needed and tweak prompts slightly to make the backgrounds feel even more relatable.

Steven, Carolyn, and Laura Sweltz felt seen.

3. We could commiserate about our eventual AI overlords. (Did you notice that I say “please” in my prompts?!) Listen, Viget has plenty of practical, healthily skeptical people who are dubious about AI. GenAI is not always a fun, lighthearted thing. But using it in a fun, lighthearted way to do something it’s really good at was a nice use case and thought-provoking exposure even for people who are not into it.

4. We could see where we all align, and where we differ! It was amazing to see just how many people love picnics, covet their caffeine, and appreciate a bike ride. It was also cool to see some unique folks who simply crave a rainy spring day, or some beloved Buc-ee’s. What a rich tapestry of individuals — literally!




v

Self-Host Your Identity Provider with authentik

Authentication! What a hassle!

Evans, where's that SAML from Earth!?

You start off simple enough — username / password authentication in your application. Then, well, someone mentions that traditional passwords are a security vulnerability, so maybe we should use one-time passwords. That inevitably leads to discussions about magic links and multi-factor authentication. Next thing you know, one dev is in a corner, rocking back and forth and muttering something about SAML, and another dev just left — walked out the door, never to be seen again.

Well, not to worry, we've got just the tool for you.

authentik is an open-source identity provider written in Python. I'm going to focus on the self-hosted version, but they also offer a paid enterprise plan if you want some extra support.

Self-Hosting

The philosophy of open-source tools and self-hosting is a big, complex topic for another post. In the world of SaaS products, you likely don't need to self-host. I quite like hosted identity providers like Clerk and Auth0. They're good and appropriate solutions for different types of apps and companies.

But I just love to self-host tools. Tinkering and toying with Docker, reverse proxies, and sometimes even server hardware is a lot of fun to me. It does add complexity in some (or many) places, but a little extra complexity means you've got a little more control over your tooling.

Self-hosting also allows me to disconnect from the Internet and still be able to work on features and enhancements in my projects. As long as I've already installed the relevant packages or pulled the right Docker images, I can keep working if I'm in a place where I can't (or don't want to) connect to the Internet. This is a small thing, but really important to me.

authentik makes it really easy to self-host your application. Right out of the gates, they provide a Docker Compose example and a Kubernetes example. Getting authentik running took me about 10 minutes using the Docker Compose example. Most of that was reading. This can make authentik a great tool during the proof-of-concept or beta phase of your application, getting authentication out of the way so you can focus on building the cool and unique features of your app.

Integrations

One of the great things that authentik has waiting for you is a bunch of documentation on integrating with a lot of tools you probably already use. These integrations range from other self-hosted apps like Outline (another favorite of mine) to cloud providers like AWS and even platforms like WordPress.

authentik's integration docs show you how to set up authentik for your existing providers and applications, so no need to dig around for the right configuration. Sure, if you're building your own application, you don't have the luxury of a README (until you write one, of course!), but don't worry — all the documentation you'll need for your choice of providers is at your fingertips. Personally, I'm fan of the OAuth2 provider for most my pet projects, but I also find the Proxy Provider to be a really great tool if you want to secure a static site that doesn't have any means of authenticating users.

Customization

This is a pretty nice default login screen, but maybe a mountain road isn't your vibe. You can change this background, add your own company logo, and add your own CSS. Just add your static files to your authentik deployment and modify to your heart's content.

But actually, that's not even the cool part of the customization to me.

authentik has the concepts of Flows and Stages that are used to determine what steps a user should take to log in, log out, and more. First, you define Stages that represent a single step of authentication — something like requiring a user to enter their username or a password. There's a whole lot to choose from. Once you've set up your Stages, you'll create a Flow, stringing those Stages together until you have a complete process to authenticate, register, or even delete a user. Flows can be imported and exported as .yaml files, making it easy to keep your Flows and Stages synced between different environments.

authentik comes with a pretty reasonable set of default Flows and Stages. If you're setting authentik up just to try it out, you might not need to add anything. They do have a couple of example Flows to get you started, though.

Flows and Stages can feel pretty intimidating. On your dev server, I'd recommend basically deleting all of the default Flows and Stages and building up new ones from scratch. It's the easiest way to learn how these pieces fit together. If you accidentally break something in dev, you can always just drop your database and spin up a fresh install.

Conclusion

authentik is an awesome tool and I've only scratched the surface of what it can do for you. As a self-hosted identity provider, it gives you a lot of control on how your services are authenticated. It's great for local development and beyond, and it has a lot of ready-to-go integrations for services you might already use.

If you're interested in further reading, I'd definitely recommend checking out the docs on Outposts and External Sources.

Hopefully this has given you some inspiration to spin up a local instance of authentik and try it out! It will definitely simplify your authentication needs.

Here's your SAML, Mr. Horrible Gelatinous Blob!




v

Building Magic with Webflow: A UI Developer's Perspective

In the fast moving and constantly changing landscape of web development, codeless solutions like Webflow and Squarespace have emerged as an alternative to more traditional development. These platforms allow users to design and build websites through intuitive visual interfaces, and are viable solutions for many use cases out there. 

For the past several months, I've been working as a frontend development support specialist alongside one of our talented designers, Blair Culbreth, who is managing a large, established Webflow project. Here are my candid thoughts and impressions from this experience, along with some critical considerations for those looking to integrate Webflow into their own workflow. Spoiler alert: while Webflow has some impressive strengths, it also comes with limitations that can be both unexpected and frustrating at times.

What Webflow Does Really Well

Small Team Efficiency

Webflow truly shines for smaller teams or products, especially those with limited resources. For a team that’s just a single designer or a small development crew, Webflow can help lower the technical debt involved with getting a website to production. By mitigating some of the more complex aspects of development such as responsive design, cross-browser compatibility, and hosting, teams are able to focus on other aspects of the site. This makes it a strong option for startups, freelancers, or small businesses looking to create professional-grade websites efficiently and effectively without the necessity of a developer.

Animation Tooling

When I say professional-grade websites, I’m talking about more than just functional designs. Webflow has some fantastic animation tooling making it incredibly simple to build rich, full-page animations and interactions without ever touching a line of code. Users can create scroll-bound animations or interactive moments of joy all from the comfort of a relatively simple and straightforward GUI. Through the use of animation keyframes, you can elevate a static site into something that feels modern and expensive. Heck, I could even see using the animation tooling itself as a prototyping tool for design handoff in a more traditional web development process. This ability to easily add sophisticated animations allows smaller teams to produce polished, dynamic websites that rival those created by much larger teams with dedicated development resources.

Documentation & Education

Beyond its design capabilities, Webflow also stands out for its educational impact. The platform offers incredible documentation that covers core frontend principles, effectively bridging the divide between design and development. Through simple, digestible, and intuitive videos and written documentation, Webflow equips designers with knowledge that shores up many concepts and intricacies of web development.

Working with Webflow provides designers with numerous takeaways they can apply to future projects, including those outside the realm of Webflow. The platform educates users on HTML structureCSS styling properties, and responsive design. This deeper understanding of web development makes designers more versatile and effective in their roles and inherently benefits communication between designers and developers, as their thinking will be more aligned with one another.

Navigating Webflow’s Limitations

Class Styles

Webflow's class-based styling system is a standout feature, especially to those familiar with CSS. It allows you to bundle properties into classes and apply them efficiently across different elements, minimizing code duplication. When used effectively, this approach facilitates the creation of reusable styles and design systems; however, mastering it requires attention to detail, similar to working with CSS directly, which can be made challenging within the Webflow UI.

Due to the separation of pages and content in Webflow, tracking down existing CSS classes and applying styles consistently throughout a project can be challenging. Keeping track of which class names apply what styles can be a struggle. While Webflow offers a Style Manager to help organize and manage classes, it can be difficult to use for quickly identifying how styles are being applied across the platform.

Moreover, the inability to open multiple pages in designer mode at once presents a significant frustration. Without the ability to compare elements across different pages simultaneously, users may face challenges in ensuring consistency and troubleshooting design issues efficiently. This limitation may lead to a slower, more cumbersome workflow, particularly in larger projects where maintaining a coherent design system is critical.

Another struggle with managing styles within the UI comes in the form of applying styles to combo classes. Combo classes are when you combine multiple classes together to create a variation or modified state of an element. Inadvertently applying styles to a combo class when intending to apply a style for the base class was a common issue I found myself running into, highlighting some challenges users should be aware of, especially when getting more familiar with Webflow.

These challenges underscore the value of implementing a strong and consistent CSS class naming system, such as BEM (Block Element Modifier). Adhering to a standardized naming convention will help mitigate some of the challenges posed by Webflow's class-based styling system, but it does come with the added overhead of needing to learn a new class naming convention.

Preset Web Elements

Webflow provides users with a diverse selection of default web elements, ranging from simple divs to intricate lightbox elements, which serve as the foundational building blocks for websites. These preset elements occasionally impose rigid structural constraints. For instance, when attempting to create a tabs menu with a filter, users may encounter a problem with adding additional elements to the tab menu block. This restriction forces users to either conform their design to Webflow’s constraints or devise creative workarounds to achieve their desired functionality.

Navigating such limitations can be challenging, particularly when striving to realize a specific design vision. It may involve exploring alternative solutions or compromising on the original plan. Yet, as users gain familiarity with the platform, those limitations can be anticipated, allowing them to develop strategies to circumvent the constraints.

Custom Scripts

One of the most powerful aspects of Webflow is also one of the most challenging features to balance. It requires careful management to avoid issues like performance degradation and increased technical debt.  It’s incredibly easy to have a website get bogged down with bloat, especially when a larger team might be working on a project.

Webflow lacks a built-in feature to view all custom scripts at a glance, making it difficult to track and manage them. Maintaining a documented list of all custom scripts used in your project and detailing their purposes and locations can help mitigate this issue, but that’s a fair amount of overhead to maintain. Additionally, custom scripts do not function in Webflow’s editor mode, requiring a site deploy for testing and troubleshooting, which can be time-consuming. 

The ability to add custom scripts opens up a world of options, including third-party plugins and libraries that can expand Webflow's native features. Tools like Jetboost or Finsweet can help fill in the gaps, and are oftentimes worth the investment as they provide relatively easy-to-use integrations that will make for a better user experience.

That’s all to say that applying custom scripts to a Webflow project is not necessarily bad, but should be approached with considerations on how to mitigate technical debt. Here are a few suggestions to help with integrating custom scripts into your Webflow project:

  • Maximize Native Features: Use Webflow’s built-in features as much as possible. If a design can be achieved with Webflow’s interactions and animations, avoid adding custom JavaScript.
  • External Development: Develop and test scripts in an external environment to reduce time spent deploying and debugging within Webflow.
  • Reusable Components: Save frequently used custom code as reusable components to simplify maintenance and ensure consistency across the site.
  • Regular Audits: Periodically review and clean up scripts to ensure that only necessary ones are loaded, improving site performance and maintainability.

Mitigating Difficulty Through Teamwork

I started this article by mentioning that I recently served as a frontend development support specialist alongside our designer, Blair, on this project. Blair took on the primary responsibility of building many of the pages, and I want to share more about our collaborative experience. Webflow is as close as you can get to building a traditionally coded website without necessarily needing to touch code, but that doesn’t mean there’s no value in having someone more familiar with the technical side of website building available. From accessibility considerations to complex layout structures, a lot of time can be saved by having a developer serve as a pseudo consultant on the project.

On numerous occasions, Blair reached out to me to help set up more complex custom implementations that required JavaScript or weren’t coming together as expected. By being able to jump in and solve those issues quickly for Blair, she was able to focus on building out the other pages. Similarly, I was able to audit and review her work to ensure it was inclusive for all types of users.

There are various development tricks we can implement to enhance user experiences for visually impaired users. For example, hiding text specific to a screen reader to provide greater context is a technique that a designer might not generally think about or even be aware of, but a good frontend developer would know to include. By being involved in the building process, I was able to highlight and advise on such instances, ensuring our project was accessible and user-friendly for everyone.

Conclusion

Webflow presents a robust solution for web development, particularly for smaller teams or projects with limited resources. Its intuitive visual interface and powerful animation tools enable the creation of professional-grade websites without the need for extensive coding knowledge. Webflow’s educational resources also empower designers to deepen their understanding of web development, bridging the gap between design and development and fostering better collaboration.

Webflow is not without its limitations. The class-based styling system, while efficient, can be challenging to manage, and the need for site deployment to test custom scripts adds to both the complexity and time investment required to build a project. Despite these challenges, many of the difficulties can be mitigated through careful planning and teamwork. Leveraging native features, developing and testing scripts externally, and creating reusable components are all strategies that can help maintain site performance and manage technical debt.

Collaborative efforts between designers and developers can further enhance the process, as seen in my experience working alongside Blair. This teamwork allows for efficient problem-solving and ensures that accessibility and user experience are prioritized throughout the project. By combining the strengths of Webflow with thoughtful collaboration and strategic planning, teams can create dynamic, user-friendly websites that meet modern standards.




v

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.




v

10 Things I Learned in My 10 Weeks at Viget

This summer, I was the Application Developer Intern at Viget. This being my first internship, I was pleasantly surprised by how much I learned. Rather than being tasked with fetching coffee or doing busy work, the internship focused primarily on our growth and development as interns. As my time at Viget comes to a close, I wanted to reflect on ten key things I learned during my experience here.

Following the real-world development cycle

Going into this internship, my development process involved me sitting down and coding until the feature was completed, and that's it. During this internship, I learned and practiced the development cycle used at Viget. For each feature, I created a Branch. Then, I submitted a Pull Request once it was completed. After that, my advisor reviewed my code and gave feedback. Once I had completed the requested changes (if any), I would rebase and merge into the main branch. This cycle made the code cleaner, and the feedback on my code always ensured I was going in the right direction.

Maintaining a clean git history

During my development process at Viget, my advisor ensured I took the necessary steps to maintain a clean git history in my projects. I put the corresponding issue number next to each git commit and pull request. This made it much easier to see which commits belonged to which feature when reviewing git history. I also learned to always use “rebase and merge” rather than “create a merge commit” when merging a pull request. This helped when reviewing git history as merge commits make it much more difficult to understand what’s going on, and rebase and merge provided a clean git history.

Getting introduced to DevOps

Nevin Morgan hosted a MicroClass where he went over the basics of DevOps. Going in, I didn’t know much about DevOps, but the class gave me a solid understanding of the basics. DevOps is a combination of philosophies, practices, and tools designed to improve the speed of development. Their responsibilities include:

  • Keeping Communication clear for development teams
  • Making sure teams continue collaborating
  • Ensuring deployments are quick and reliable

I also got the chance to pair with Nevin when he set up AWS deployment for one of my projects, and when he was setting up Grafana for Viget. Getting to see DevOps in action gave me a good idea of what goes into being part of the DevOps team.

Learning to work with clients

At the start of our intern group project, Nathan Long gave us a presentation on what it's like to work with clients. He covered the typical client project cycle, client presentations, and how to handle client feedback. For our project, we simulated a client relationship with Viget as our client. They provided us with their requirements, and me and the other interns planned out the details of what we would deliver. Throughout the process, we gave several client presentations, received valuable feedback, and iterated on our product. Two weeks later, we had a finished product, which we presented to the client in a live demo. This whole process was designed to mimic what Viget goes through with real clients, and seeing the different perspective required when working with clients was really eye-opening for me.

Exploring digital accessibility

Nathan Schmidt hosted a MicroClass for the interns on Accessibility. He gave us an overview of what digital accessibility is and who it impacts. I learned that digital accessibility is the lens through which we ensure that people of all abilities, and particularly those with disabilities, are able to engage with the digital world. Every website is graded to a level set from the Web Content Accessibility Guidelines (WCAG). These guidelines include video captions, text size, color contrast, and many more requirements. It is the industry standard to follow these WCAG guidelines so that your website can be accessible to a broad range of consumers.

Building confidence in public speaking

When the summer began and I learned that I would need to present to the entire company, I felt intimidated. Public speaking has always been a source of anxiety for me, but I had numerous opportunities to work on this skill. Throughout the summer, I became increasingly confident. First, my fellow interns and I presented our group project to everyone at Viget at the company-wide all hands meeting known as TTT. I presented my personal project to the Dev team, discussing the libraries I used and walking through my code. The most significant presentation I delivered was my final one, where I spoke to everyone at Viget about my Gap Year through a Viget Tradition known as LabShares. Public speaking is a skill that improves with practice, and the various opportunities I had greatly boosted my confidence in this area.

Diving into Vanilla JavaScript

Going into this summer, I had never written a line of JavaScript in my life. I quickly learned that JavaScript is essential if you’re going to work in web development. On my personal project, which was an audio sharing social media app, I had a for you page, and I wanted to make the page update as soon as the user went to the next sound. This would require me to write JavaScript. I went through and wrote Vanilla JavaScript to update all the necessary information from the server's response. Although it was a challenging and tedious process, it significantly enhanced my understanding of how websites work and the role of JavaScript in web development.

Getting my feet wet with Rails

For the first half of the internship, I got my foothold in Ruby on Rails. This was my first time writing in Ruby, so there was a bit of a learning curve. I started with the Rails tutorial and then made a Hacker News clone. This exposed me to a broad range of the application stack and got me prepared for the Intern project, where I also used Rails. I found Rails’ Model, View, Controller setup to be very intuitive, so the learning process was relatively painless.

Discovering the benefits of Tailwind

Being the only Application Developer Intern, my focus throughout the internship was primarily on the back-end. However, I did have the chance to use Tailwind for the first time during my personal project. The biggest thing that stuck out to me was how it was convenient to not have to go through and change the stylesheets myself. With Tailwind's utility-first approach, you can quickly apply predefined classes for spacing, colors, typography, and more, without having to write custom CSS. This makes it much faster to prototype and iterate on designs, as you can see changes immediately by simply adjusting the class names in your HTML.

Exploring the Basics of React

Chris Manning hosted a MicroClass on React. I had never actually used React, but he made the class very beginner friendly. React is a JavaScript library, whose main strength is how dynamically it responds to user input and cascades UI changes. Chris went over JSX and React components, props, children, and state memory. I didn’t have time to actually write any React this summer, but I appreciate that Chris hosted this class after I said React was something I was interested in!

Reflecting on what I’ve learned here at Viget, I realize how invaluable this experience has been for both my personal and professional growth. From learning Rails and JavaScript, to understanding the intricacies of client relationships, I've gained a wealth of knowledge that extends far beyond technical skills. The opportunity to work alongside experienced professionals and receive constructive feedback has been a huge source of development for me. As I move forward, I am excited to apply these lessons and continue exploring the world of Software Development, confident in the foundation this internship has provided.



  • Code
  • News & Culture
  • Back-end Engineering
  • Internships and Apprenticeships

v

Evolving Traditions: 15 Years of Viget Internships

This week we will bid farewell to our fifteenth cohort of summer interns. Ciel Park (UI Developer Intern), Faye Stover (Product Designer Intern), and Paul McKissock (Application Developer Intern) joined our team ten weeks ago and have been hard at work learning and growing, teaching and sharing, and iterating ever since – and so have we. 

Viget’s 15th Summer Internship Cohort: Faye Stover, Paul McKissock, Ciel Park (left to right)

At Viget we are committed to fostering curiosity and drive both for budding engineers and designers but also for our team of full-timers who are eager to learn themselves and flex their mentorship muscles. As we’ve shared over the years, the internship is one of our favorite traditions and while a lot has changed in fifteen years, that commitment remains the same. 

Here’s a quick look at three core aspects of the Viget internship that remain flexible. 

Cohort size and available roles.

We are not married to a specific number of interns. We recruit for and match interns with available mentors who serve as our interns’ dedicated advisors.

Working location. 

This summer our interns primarily worked from our Falls Church, Virginia headquarters. We required interns to work in the office for the first three weeks of the program and the last. During weeks four through nine they were able to work remotely two to three days a week. In the past the internship has been fully in-person and fully remote

Cross-discipline internship project. 

Interns can expect cross-discipline collaboration during their time at Viget but how exactly that takes shape remains flexible. In years past interns spent 8 weeks coming up with, designing and building a working product. This year, with our smaller cohort of interns, we opted for a smaller approach to the group project. The project was pre-defined, scoped by our advisors, and happened over just two short weeks.   

Earlier this summer we hosted an internship alumni panel and invited Hayley McMillon (2022 Summer Cohort), Andrea Brucculeri (2019), Gabriel Kay (2019), and Vigenesh Gopalan (2018) to discuss lessons learned at Viget, life after Viget, underrated skills worth developing, tips for remote collaboration and more. The event was open to all and both current staff and other alums sat in on the moderated panel discussion. It was awesome, and everyone – long-timers and interns alike – left feeling inspired. This is my favorite aspect of the internship, our alumni network, and how our interns graduate to be active contributors.

Summer 2024 Internship Alumni Panel

I’m looking forward to staying in touch with Ciel, Faye, and Paul and I cannot wait to see all the wonderful things they accomplish. 

Does this sound like an experience you want to be a part of? We’ll host our 16th cohort of college students and recent grads next summer. Bookmark our internship page to keep an eye on future opportunities. 



  • News & Culture
  • Internships and Apprenticeships

v

Motion Magic: Project Insights From My Viget Internship

When we open an app or website, we do so to accomplish a task or find information. A well-designed user experience ensures users can achieve their goals efficiently. But what keeps us engaged beyond basic functionality? What differentiates a mundane interface from an exciting one? In my opinion as an up and coming UI developer, one key element is motion.

During my summer internship at Viget, I had the opportunity to dive deep into the world of agency work. From getting the chance to contribute to client sites to participating in a hackathon and pursuing a personal project, I seriously leveled up my stack and gained valuable development experience. Not to mention the amount I learned from exceptional, dedicated mentorship and micro-classes on everything from React to SQL to business models. 

However, coming into the internship, I had the specific goal of learning how to add motion to my web projects. I walked in on day one with no idea where to start, and now I’m leaving my last week with a complex knowledge of Rive, canvas elements, JavaScript animation, GSAP, and more. Here’s how… 

Spinet

In this two week hackathon project, I worked alongside Faye and Paul, the Product Designer and App Developer interns, to create a spinning wheel name picker. During the first week, I took on branding and visual design work. 

I spent the second week implementing wireframes. Through this project I learned how to transform client specifications into design directions, a style guide, and ultimately, UI components.

For this app, the motion of the spinning wheel was critical to the experience. Initially, client feedback indicated that the spin felt too uniform. I adjusted the motion parameters by extending the slowdown time and changing the easing function from linear to cubic, which increased feelings of suspense at the end of the spin animation. 

To add a level of joy and celebration to the winner announcement popup at the end of a spin, I incorporated confetti animations. In doing so, I discovered the world of JavaScript animation libraries that make implementing animations as easy as simple as adding the script to my HTML and adjusting the timing and placement of the animation object. Finally, we had ultimately decided on a modern, clean-cut video game aesthetic for the branding, and pulled this in through inspired sound effects, the logo design, and a 3D button component with a click animation accomplished entirely through Tailwind. 

Luna chatbot

After the hackathon, I got the chance to work on a personal project of my choice: an AI mental health chatbot inspired by tools like Woebot and EarKick. I was motivated by the question of what could make conversational AI feel less intimidating and more empathetic. My answer was an AI support companion with an animated avatar to enhance feelings of emotional connection and understanding. 

To get started, I experimented with various chatbot APIs and found that the Llama3 model was the best at following system prompts and offered the most natural interactions. A huge part of this project was the chatbot’s expression animations. I surveyed several popular tools and found Rive was the best fit for this, offering intricate animation capabilities, easy web integration, and a state machine for managing overlapping states and complex transitions.

The first step of animating in Rive is to create a design. Luckily, Rive has a vibrant open-source community, and I learned a lot from examining and remixing community files. The second step was learning to create the animations themselves. This was my first time animating anything, but the concept of keyframes was relatively intuitive, and the UI reminded me of video editing software, like iMovie, I’d used in the past.

The third and most challenging step for me was making all the animations work together in a state machine. 

This is the logic that connects animations together, taking input values that determine when to transition between states. Getting smooth animations between emotional states required a lot of rewiring and experimenting. Finally, embedding the Rive file in my project and linking the emotion data from API responses to the animation inputs was relatively straightforward using vanilla JavaScript. 

In conclusion

Animations, whether simple or complex, add a layer of interactivity and visual interest to digital products. Over a short 10 weeks, my internship projects allowed me to explore UI development, modern animation tools, and motion using CSS and JavaScript.

If you’re interested in bringing ideas to life and sparking joy through motion design, then diving into a passion project, seeking inspiration from the community, and exploring tools like Rive and GSAP will definitely kickstart your journey!



  • Code
  • Internships and Apprenticeships

v

Use Behavioral Analytics Data to Make Your Site More Effective

Behavioral analytics are a great way to get a sense of what users are or are not doing on your website or app. While behavioral analytics may not provide insights into why users are behaving a certain way, this method does provide a quick and cost-effective way to see what your users are currently doing at scale. Knowing how your users are engaging with your website or product can help you make informed decisions that have a positive impact on engagement and conversions.

Here at Viget, we use behavioral analytics data for a number of use cases:

  1. Our client has a specific question about a certain aspect of their website or app (e.g., a specific user flow or content type) and wants to learn more about how and when users are engaging. 
  2. We are redesigning a client’s website and want to get a sense of where the current experience is excelling or falling short.
  3. We are conducting an annual analysis to help clients keep an eye on potential areas of growth or stagnation. 
  4. We are reviewing behavioral changes on a site or app after launching a new experience or feature to assess performance.

But what kind of insights can you expect to find from behavioral analytics data? 

It ultimately depends on the website or app, the users, and the kinds of questions you are asking, but let’s go through a few different examples of what kind of information you can gain from behavioral analytics tools.


Who is using your website or product?

Understanding who is using your website can provide helpful context on your user base and potentially unlock growth with new user groups you may have been unaware of. To investigate this, we may look at geographic location, language, device type, and any other demographic information that may be available. Sometimes this kind of data provides what I like to call descriptive information—information that often doesn’t feel immediately actionable but can become more useful relative to other data points. This could come from comparing your data to last year, to industry standards, to other content on the website, or it might come from comparing it to an assumption that an individual or organization holds. 

Here are some examples of findings that shed light on who was using the website or product:

32% of sessions were from users outside the United States. 
  Through a previously conducted survey, we were aware that some users were looking for content that was not specific to the United States. This metric helped us better gauge the size of that need.
97% of Canadian sessions interacted with the website in English, with only 3% of Canadian sessions using French.
  We were unsure to what degree French content needed to be prioritized and this metric helped provide a sense of scale.
15% of searches were conducted on a mobile device. 
  Although 15% may seem low, this metric was actually higher than expected because there were known issues with the mobile search experience. This demonstrated that even though the mobile experience was harder to use than the desktop version, users were still inclined to use it, further illustrating the importance of improving the mobile experience. 

How do users get to your website or product?

Knowing how users navigate to your website or product can highlight what traffic sources are particularly effective in driving conversions, but it can also help to provide important context on user expectations or goals. To understand this, we look at both the source/medium that brought them to the website as well as the first page they viewed. 

For example, users might:

  • Come from google and land on a blog article
  • Go directly to your home page
  • Come from an email referral to a donation page 
  • Learn about you from ChatGPT and land on your About page

From there, we might look at engagement rate, conversion rates, or other metrics to get a sense of what these users are doing and whether anything stands out as particularly effective or ineffective. 

Here are some examples of acquisition insights that informed our understanding and approach:

Only 10% of sessions started on the home page, with most users starting much deeper in the site on content-specific pages.
  Because only a small portion of users entered on the homepage, we could not solely rely on homepage messaging to orient users to the site. This highlighted the importance of providing sufficient context on any page of the site to ensure that users navigate to their desired content, regardless of what page they land on.
Although the paid ads were effective in driving users to the website, those sessions had abnormally high bounce rates, with one traffic source having a 95% bounce rate. 
  This indicated a potential mismatch between what users expected based on the ad, and what was actually on the page.
Organic search brought in a large amount of new traffic to their site through the blog pages and while users engaged with the blog content, they were not engaging with the CTAs. 
  Because these new users were potentially learning about this organization for the first time, the donation CTAs were likely not the best fit, and we recommended shifting the CTAs on those pages to focus more on learning about the organization.

What content or features do users engage with?

Here is where we start to get to the meat of what your users are actually doing on your website or product. Knowing what users are doing and what they’re not using can help to establish priorities and inform decisions. You might be surprised to learn that users are actually engaging with specific features or content quite a bit, but others are barely used. If the content or feature is surprisingly popular, then we likely don’t want to outright remove it and may instead consider iterating or leveraging that offering more. If users aren’t engaging with content or a feature, it may be worth considering the effort to maintain and iterate on that offering. 

Here are some examples of engagement insights that helped us identify opportunities related to content or features:

Less than 1% of users were engaging with a particular feature. 
  These same users were showing high engagement with other features though, indicating that users either didn’t know this feature existed, knew the feature existed but didn’t understand the value add, or the feature was simply not something they needed.
For a highly engaged audience, there wasn’t a standout page that most users visited. These users viewed a variety of pages across multiple sessions, typically viewing highly specific content pages. 
  This indicated that instead of relying on a single page to drive conversions, getting users to the specific details they needed was likely a better approach in getting users to try the product.
Nearly 84K sessions engaged with a particular content type. 
  While this was lower than other content types, it was much higher than expected. It was largely organic traffic and the sessions were highly engaged. We recommended doing some additional research to better understand the potential opportunities with that type of content.

What is the user journey or path?

Another major area of investigation is the sequence of steps users take when viewing content or completing certain actions. This could be perusing content on the website, going through a signup funnel, or checking out to make a purchase. 

This helps us identify:

  • the actual paths that lead to conversions (which is not always the path we assume it is) 
  • areas where users drop off at key points in the funnel
  • moments where users have to “turn around” in the journey, because the path laid before them doesn’t align with their needs 

This information can help you build towards a frictionless experience that encourages users to sign up, complete a purchase, or find the resources they need.

Here are some examples of user journey insights that helped us understand where there were existing points of friction for users:

While the CTA to demo the product appealed to users and they were quick to engage with it, it often resulted in users backtracking to the previous page. 
  We hypothesized that users were eager to get to the demo, but were moving too quickly and missed important context, resulting in them having to go back to a previous page. We were able to confirm this with user testing and recommended transitioning some of that context to the CTA page.

What “turning around” in the user journey can look like:

A select few products had abnormally high drop off rates, but at different stages depending on the product. 
  For one product, there was an abnormally high cart-abandonment rate, and for another product, there was an abnormally low add-to-cart rate. Based on these findings we recommended looking further into what is impacting a user’s purchasing decisions.

What dropoff can look like at different stages:

The Ecosystem at Large

Some clients have a larger ecosystem of products or services, and it’s important to look at how users engage with and navigate across the ecosystem. This might include subdomains for a shop, a marketing site versus the product site, help documentation, etc. By looking at the larger ecosystem we can reveal important connections that are missing or connections that could be strengthened.

Here are some examples of insights that demonstrated a need for changes in those ecosystem connections:

For sessions where a user was looking for a particular kind of resource, 95% of the searches were done exclusively in a single subdomain or microsite.
  Through user interviews we were able to confirm that this siloed experience was intentional for experienced users but unintentional for less-experienced users, who were largely unaware of the other parts of the ecosystem that were available. We recommended making changes to improve discoverability of those other areas.
For sessions where a user navigated between two domains, 75% of sessions navigated to the other domain to view documentation specifically.
  Yet, depending on the product, sometimes the documentation was hosted on a subdomain specific to documentation and sometimes it was available on the product domain. This created an inconsistent experience where for some products, users could find what they needed on the product website, but for other products, users were sent to an entirely different subdomain. We recommended creating a more consistent experience for users, where regardless of the product, the documentation would be found in the same location. 

Here at Viget, there are a wide variety of insights we may discover for any one project through behavioral analytics. These insights can help to identify new user groups, help to prioritize content or features maintenance and updates, or bring to attention moments in the user journey that are causing friction. These opportunities can help you bring in new users and retain your existing users, by providing an experience that aligns with their needs, whether that is finding resources, getting involved in a community, or making a purchase.  

If you’re interested in making your website or application more effective for your users by leveraging the power of behavioral analytics data, we’d love to hear from you




v

5 Ways to Make Your Next In-Person All-Hands Event Worthwhile

In recent years, as distributed work has become the norm, all-hands trips have become more commonplace. Even companies that have always done them now see their importance in a new light. They are expensive and demanding for everyone involved, but when they’re done well they can be incredibly impactful. Are you bringing your team together and feeling the stress of getting it right? Designing the time together takes strategic thinking, logistics planning, and the confidence to ask everyone to contribute to the event’s success.

Last week, we came together to connect, celebrate each other, and look forward to a bright future in our quarterly all-hands event we call Third Third Thursday or TTT. It was our first in-person all-hands event since May 2023. At Viget, we actively build our culture together. The responsibility doesn’t fall on just a few individuals' shoulders. Our events are successful because individuals show up, speak up, listen, and honor the limited time we have together in-person. This is evident in the chats over breakfast pastries, the all-in approach to competitions breakout sessions, and the peer talks and discussions throughout our events. This connection and camaraderie doesn’t just happen, we work hard to make it happen. 

Reflecting on last week’s event (and 7 years of other events), I want to share these five key planning tips to help you craft a successful event. 

Leverage your physical space to help achieve your event goals. This fall we had a smaller number of attendees and we wanted to encourage discussion throughout the event so we set up the room in large U shape to foster conversation. We also made the most of our exterior space, which featured a fire escape staircase, by hosting an egg drop competition. 

Over communicate, especially around when team members can expect breaks and when they can expect to be fed. As the event lead, I share my phone number multiple times ahead of and throughout the event. We also make sure to communicate in dedicated channels, including an event Slack channel for all attendees, a behind-the-scenes Slack channel for presenters only, and an event website. We share important key information like bus schedules and flight confirmations via email. In advance of the big day, we shared this slide with our team to both inform and inspire. 

Leave room for unstructured time and connection. Over the years we learned that some of the best discussions and a-ha moments come from chats over a meal or a snack during the “unplanned” parts of the event. Now we plan ahead for these, leaving ample time for unplanned, impromptu a-has. We think about airport Uber rides, charter bus rides, morning runs, evening board games, or late-night drinks and look for ways to grease the wheels of serendipity. This was especially important for us this fall since it had been so long since the last time we all gathered together

Look for ways to celebrate what is unique to your company. One pretty fantastic thing that comes with a quarter century in business is the community we’ve built along the way. We make a point to keep up with previous Viget employees who we proudly call our alumni. We love our alumni and enjoy recognizing their contributions to Viget. One way we do so is with annual picnics, which we host when the most current Viget employees are in town for an event. These picnics are often a great mix of reconnections and networking.

Find ways to surprise and delight. Think big and small. For example, this fall we put colored pencils and butcher block paper out during our meeting time. Our autumnal decor included blue(ish) and orange pumpkins (Viget colors!). We made a subtle callout to an internal project by serving french fries as our afternoon snack. And we surprised our team with Unreal treats for their bus rides home. The treats served as dessert and a means for us to introduce our next in-person event, our spring TTT, aka Viget25. 

Some companies advocate for all-hand retreats to be social and relaxing, but not “productive.” They tout a meeting-free event. At Viget, we see the meeting time as crucial because that is when peers share knowledge, reflect on their recent work, showcase client impact, and highlight new ideas and personal growth. Similarly, our co-founders reflect on Viget’s performance and share thoughts on the upcoming business direction. The meeting sparks genuine inspiration and creates a time for us to remember what brought us to Viget in the first place – to build world class tech in support of our clients. 

On the heels of a successful gathering, it’s time to start planning the next one. For our next event we’ll head to the Allegheny Mountains where we’ll leverage a unique and memorable venue, offer plenty of unstructured time for connection (with each other and nature), loop in alumni where appropriate, plan inspiring meeting content, enjoy many meals and treats together, and of course find ways to surprise and delight. 

Work-related travel isn't for everyone, but if you know someone who appreciates the idea of dedicated time to connect with and celebrate their peers, we’re hiring. And to all the culture champions and event planners out there, good luck with your next all-hands! 




v

Affinity Acquired by Canva.com

This post: Affinity Acquired by Canva.com was first published on Beyond Photo Tips by Susheel Chandradhas

Today, Affinity and Canva, together announced the acquisition of Serif, the makers of the Affinity apps, by Canva. This is a significant development in the progress of the Affinity suite, and we are both excited, and hesitant at this development. What Is Affinity? Affinity is a suite of apps that allows designers, photographers, and publishers […]

This post: Affinity Acquired by Canva.com was first published on Beyond Photo Tips




v

RIP a Livecast #635 – Liquor-ish

Rob is back from LA and shares some stories of going to a listening party and shooting guns. Then, Noa talks about shooting guns. We learn of Gene Simmons' positive […]



  • RIP a Livecast

v

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 […]




v

RIP a Livecast #637 – 24 and Stupid

We kicked things off by talking about the new member of Noa's family. We then discussed the MTV Video Music Awards, and Madonna's "controversial" look. We also discussed Megan Fox […]



  • RIP a Livecast

v

RIP a Livecast #638 – Tasteful Chinstrap

We want to thank the drama Gods for gifting us with this silly MGK vs. Corey Taylor feud. Rob gives the full rundown of what happened at the top of […]



  • RIP a Livecast

v

RIP a Livecast #639 – Leak After Leak

We kick things off by talking about the early 2000s. We also discuss the latest Machine Gun Kelly drama. Then, we discuss a group of metalheads who were denied an […]




v

RIP a Livecast #640 – Neigh Means Neigh

We kick things off by talking about Facebook's downtime. We learn about some of the less-flattering things GG Allin did. We briefly speak to Jordan from Dark Saga, a band […]




v

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). […]




v

RIP a Livecast #642 – Vinceable

We kick off the show talking about the sad news of Vince Neil falling off a stage last weekend. We talk about Rob Zombie's Munsters reboot and then transition into […]



  • RIP a Livecast

v

RIP a Livecast #643 – The Armorist

Rob, Sid and Darren kick off the show this week talking about what they like and dislike about Halloween. We have an update on Vince Neil, check with the Alec […]




v

RIP a Livecast #644 – Nut Cadence

Rob kicks things off talking about his experience at the GWAR show. We learn of No Nut November and somehow spend way too much time talking about Baby Daniel. We […]



  • RIP a Livecast

v

RIP a Livecast #645 – Backstory and Frontstory

We talk about David Ellefson's absurd quote comparing him to Jesus. Speaking of Jesus, we check in with Marilyn Manson's Christianity. We discuss the latest NFT craze, Seinfeld, the Golden […]




v

RIP a Livecast #646 – Joke Treadmill

We kick off this week's show with an important announcement. Loni joins us this week. We discuss the Brass Against onstage urination incident in great detail. We talk about Ace […]




v

RIP a Livecast #647 – Help Me How To Live

We kick things off on this edition talking a lot about the controversial Kid Rock song "Don't Tell Me How to Live." We talk about a weird video Kid Rock […]




v

RIP a Livecast #648 – Cat As Trophy

We have a big announcement at the top of the show and some fun stories to discuss. We kick off the show revealing our new podcast name – RIP a […]




v

RIP a LIVECAST #649 – Specially Speaking

It's a new era for the show, and we kick it off with a new voice. Sid explains all the different types of Drag Race there are. Rob explains poppers. […]



  • RIP a Livecast

v

RIP A Livecast #650 – Splashing the Gooch

We kick things off talking about Warsteiner beer, and Rob recalls a notable part of his trip to Germany. Rob discusses a previous feature on the site, the Suicide Girl […]




v

Squared Circle Pit #77 – Justin Whang talks old-school ECW and his favorite wrestlers

Internet sensation Justin Whang enters the Squared Circle Pit. He talks about his favorite wrestlers and metal bands growing up, staying up late to watch ECW, his thoughts on the […]




v

RIP a Livecast #651 – Basquiat Scampi

We kick off the show talking about how old we all are. We then discuss the recent messages from Kid Rock and Monster Truck where they act like they're not […]




v

RIP a Livecast #652 – Get a Good Spin Going

We kicked things off on the final Livecast of 2021 with Sid telling a scary story about his mother. Rob tells the latest stories of geriatric interactions at his Russian […]



  • RIP a Livecast

v

RIP a Livecast #653 – Celebrity Rug Pull

We kick things off wishing Darren a happy birthday and hearing about his New Year celebration. We briefly discuss the upcoming riot anniversary and the current state of the pandemic. […]