How to Automatically Tweet When You Publish a New Post in WordPress

Do you want to tweet your newly published blog posts automatically?

Twitter is one of the best platforms to let your followers know whenever you publish a new post in WordPress. By tweeting new posts automatically, you can save time while growing your Twitter followers and website traffic.

In this article, we will show you how to automatically send a tweet when you publish a new post in WordPress.

How to auto tweet new posts in WordPress

Why Automatically Tweet New Blog Posts on Twitter?

Twitter is a great place to engage with your audience and build a following. However, it can be time-consuming to manually send out tweets whenever you publish a new post on your WordPress blog.

That’s where automatically sharing new blog posts on Twitter comes in handy. You can provide fresh content to your Twitter followers to keep them engaged.

That said, let’s look at how you can automatically Tweet whenever a new post is published on your WordPress website.

Automatically Share New WordPress Posts on Twitter Using Uncanny Automator

The easiest and most reliable way to tweet newly published content in WordPress is by using Uncanny Automator. It’s the best WordPress automation plugin that helps you create automated workflows without having to code.

Uncanny Automator

For this tutorial, we’ll be using the free version of Uncanny Automator, since it includes a Twitter integration.

There’s also an Uncanny Automator Pro version that unlocks more integrations like Google Sheets, Twilio, Slack, and others. It also offers advanced features like delayed or scheduled actions, buttons that can trigger any automation, and much more.

You can see our guide on how to create automated workflows in WordPress for more examples to reduce admin tasks and save time.

To get started automatically tweeting new posts, you’ll first need to install and activate the Uncanny Automator plugin on your website. For more details, you can follow our tutorial on how to install a WordPress plugin.

Upon activation, you’ll need to navigate to Automator » Settings and then select the ‘Twitter’ tab. After that, go ahead and click the ‘Connect an Account’ button.

Connect your Twitter account

On the next screen, you’ll need to allow Uncanny Automator to access your Twitter account. To do that, simply click the ‘Authorize app’ button.

Authorize Uncanny Automator to access Twitter account

You’ll now be redirected back to the Uncanny Automator settings page. You can see that your Twitter account will be successfully connected.

See your Connected Twitter account

Next, you’ll need to create a recipe to automatically send tweets when you publish a new blog post in WordPress.

To start, simply head over to Automator » Add New from your WordPress dashboard. Now, you’ll need to select a recipe type by choosing either logged-in users or everyone.

Logged-in recipes can be triggered by only users that are logged in to the website. However, if you want anyone to trigger the recipe, then you should select the ‘Everyone’ recipe type.

You can go ahead and select the ‘Logged-in users’ recipe type and then click the ‘Confirm’ button.

Select the logged in recipe type

After that, you’ll need to add a title for your recipe and then select ‘WordPress’ as your Logged-in triggers integration.

Select WordPress as your integration

Next, you will see a list of triggers to choose from. Go ahead and select ‘A user publishes a type of post with a taxonomy term in a taxonomy’.

Select a trigger

Now you can choose which content you’d like to automatically share on Twitter by selecting a ‘Post type’ from the dropdown menu.

For instance, if you want to share all blog posts, then simply choose the ‘Post’ option. You can also decide if you’re going to share posts from a particular category or tag by changing the Taxonomy options.

Choose post type to share on Twitter

When you’re done, click the ‘Save’ button.

Next, you’ll need to add an action for your recipe. An action is something that you want to do when the recipe is triggered, like sharing your content on Twitter.

You can start by clicking the ‘Add an action’ button.

Click add action button

Now select ‘Twitter’ as your integration under the Actions section.

Select Twitter as your Action

After that, you’ll need to choose the ‘Post a status to Twitter’ option for your action.

Choose your action for Twitter

Next, go ahead and add a Status that your followers will see on Twitter when new content is published.

Uncanny Automator also offers different options to customize your Tweet. For example, you can click the (*) asterisk button to the right of the text field and select ‘Post title’ and ‘Post URL’ to automatically appear in your Tweets.

Add a Twitter status

You can use the Image URL field below if you want the same image to appear with every blog post that’s tweeted out.

However, if you want your blog posts’ featured images to appear instead, then you’ll want to see our guide on how to add Twitter cards in WordPress.

Don’t forget to click the ‘Save’ button when you’re done.

Now you’re ready to publish your recipe. All you have to do is click the toggle under the ‘Recipe’ meta box and change the recipe status from Draft to ‘Live.’

Publish your recipe

That’s it! Uncanny Automator will automatically tweet when you publish a new blog post on your WordPress website.

You can now publish a new blog post and then visit your Twitter profile to see your tweet with the custom status.

Automatically share Tweets when publishing new post

We hope this article helped you send automatic tweets when you publish new posts in WordPress. You may also want to look at our tutorial on how to choose the best blogging platform and the best WooCommerce plugins for your store.

If you liked this article, then please subscribe to our YouTube Channel for WordPress video tutorials. You can also find us on Twitter and Facebook.

The post How to Automatically Tweet When You Publish a New Post in WordPress appeared first on WPBeginner.

WPCloudDeploy Brings Site and Server Management to the WordPress Admin

WPCloudDeploy recently launched version 4.10.5 of its rapidly-maturing WordPress plugin of the same name. The project is a WordPress-native replacement for SaaS services like Cloudways, Ploi, SpinupWP, and others.

Customers still need to hook up to a cloud server provider, such as Digital Ocean, Linode, AWS, or elsewhere. However, the project seeks to cut out the middleman for developers and agencies running multiple sites. They are specifically targeting those who would routinely manage 20 or more.

“It’s a true plugin where everything you need runs on your own site (except, of course, the other servers you are provisioning and managing which reside at their respective cloud server providers),” said WPCloudDeploy owner Nigel Bahadur.

List of servers through the WPCloudDeploy plugin in the WordPress admin.
Server list screen.

Technically, WPCloudDeploy opened to the public in March 2020, but Bahadur was not ready to aggressively start letting the community know about it. He said the team is now at a point where they have a core group of users who are happy with the plugin. They have been rolling out new functionality every month for a year and a half and feel like it goes above and beyond alternatives.

“We were basically in stealth mode for most of that time — we did enough marketing to get a core group of users and then tried to make those users happy,” he said. “We even offered a heavily discounted lifetime license last year during the Black Friday sales period –- the folks that purchased then are very happy right now.”

With a mature project, it is time to branch out into the larger WordPress developer and agency market.

The plugin promises its customers that they can deploy unlimited WordPress-optimized servers and sites to any cloud or bare-metal server. It has direct integration with 10 of the most popular cloud server providers.

Services screen for the WPCloudDeploy WordPress plugin in the admin.
Server status and overview screen.

However, provider integration is limited to which pricing plan the customer decides on. The core tier, which costs $199 per year, only works with Digital Ocean. The business tier runs $499 and adds Linode, Vultr, and UpCloud to the mix. For the full range of providers, customers must upgrade to the all-access plan for $799. Both of the top tiers also have a lifetime purchase option.

Each tier of the plan is not merely limited to integration with more providers. For example, agencies can sell site and server subscriptions via WooCommerce through the business or all-access packages. White label and teams features are available at all levels.

Selling Subscriptions through WooCommerce

WPCloudDeploy allows agencies to sell subscriptions to cloud servers or WordPress sites through WooCommerce. Because of the feature’s recent interest, Bahadur said it will likely be a focus area next year for more enhancements.

“For servers, you can create subscription products where the user gets to choose the provider and location,” he said. “Or you can create them where each product represents a single provider (useful if you want to price your AWS servers differently from your DigitalOcean servers).”

They have their own separate service that builds on top of this called WPCloudPanel. The team created it with Beaver Builder, WooCommerce, WooCommerce Subscriptions, and Ninja Tables. The entire site required no additional custom code.

WPCloudPanel's WooCommerce-built pricing and sales screen.
WooCommerce-integrated sales page.

“For sites, you can create subscriptions where the site is automatically placed on a particular server in a particular region,” said Bahadur. “Or you can create them where the site is placed on any available server from an admin-defined list of servers. It’s a great way to get a highly customizable end-user purchasing experience using a toolset you already know.”

Developers and agencies are not necessarily limited to WooCommerce. Instead, they can take the team’s code and port it to other eCommerce or membership plugins. One such customer is currently working on a MemberPress solution.

“Since the WPCloudDeploy code is just hooking into various WooCommerce actions and filters, it’s basically just finding a similar hook in their favorite membership plugin, copying the relevant parts of our WooCommerce integration code, and then ripping out and replacing the WooCommerce-specific function calls,” said Bahadur.

From Inception to the Future

Bahadur said his team started the project to meet their own needs. “We really liked the idea of being able to use our own servers for WordPress sites. But at the time, there were still a lot of security questions and other usability and support issues that we were running into from the usual pool of SaaS providers.”

He then decided that his team would build something themselves. Jokingly, he said he completely underestimated the project and how far he would take it.

“I can’t say that, back in 2019, I looked too far beyond the WP ecosystem because what I wanted was WP-specific functionality,” he said. “Cloudways was one of a number of providers I was using at the time, and they offered other services beyond WP. But the overall concept was the same whether it was WP or a server that was suitable for another ecosystem. I think I looked at every WP option there was at the time, including command-line services like WordOps.”

He said he was not necessarily sure it was important to have such a project in the WordPress space.

“I think what is important is to constantly remind folks of how much WordPress can do, how powerful it is, and to keep battling against the perception that WordPress is less secure than other options,” said Bahadur. “If you can use a WordPress plugin to run and manage all your servers and sites and/or even act as a hosting service, then we’ve pushed the WP boundaries far beyond what anyone thought of doing two years ago.”

He thinks it is even more important that WordPress professionals to be able to build products that compete against the feature depth and “sexiness” of SaaS services.

“Think about how much more capital would stay within the WP ecosystem if you had a project management plugin that was as good as, say Clickup.com or Monday.com,” said Bahadur. “Or a CRM plugin that was as good as Hubspot. But to build plugins with that level of polish requires lots and lots of capital in the first place. Even though WP is a billion-dollar ecosystem, somehow we still don’t have the ability to finance the build-out of world-class functional components with a world-class UX experience, and I think that’s a shame — and a major opportunity for VCs.”

He does not think WPCloudDeploy has quite met the smoother UIs of SaaS services yet. However, he believes it can prove that it rivals or exceeds such competitors in terms of functionality.

“So the next time someone asks, ‘can you really build that on WP?’, maybe they can point to WPCD and say, ‘Hey, if you can build this on WP, then, hell yeah, we can build that thingamajig that you want…,” said Bahadur.

The team maintains a Trello board with a public roadmap. The most-requested feature right now is support for OpenLiteSpeed, an open-source web server.

However, Bahadur said the most tantalizing possibilities for the long term come from working with the REST API.

“Unlike SaaS tools, you’ll be able to customize it using our built-in ones as a template,” he said. “Ambitious agencies will be able to add their own plugin to extend our REST API without waiting for us to add new endpoints that meet their needs.”

Eventually, the core plugin will be available on GitHub. Developers will be able to contribute new endpoints to the core product via pull requests.

Hacktoberfest Adds GitLab Support, Updates Participation Requirements to Combat Open Source Project Spam

The 8th annual Hacktoberfest is underway with a few important changes this year. Hacktoberfest, a virtual event sponsored by DigitalOcean and community partners, has traditionally encouraged open source contribution during the month of October by rewarding participants with a t-shirt for submitting pull requests. The initiative has added support for participation on GitLab this year, a highly requested expansion that will include more open source projects that aren’t hosted on GitHub.

Participation has grown from 676 people the first year to over 150,000 in recent years. In 2021, the program has been changed to be only applicable to opt-in repositories after being linked to an influx of spam for open source maintainers in previous years. Maintainers of popular projects were getting frustrated by wasting their time handling nonsense PR’s and marking them as spam during Hacktoberfest.

Starting this year, pull requests will only count towards participation if they are in a repository with the ‘hacktoberfest‘ topic and once they have been merged and approved by a maintainer or labeled as ‘hacktoberfest-accepted.’ Participants must contribute four accepted PR’s to an opted-in repo in order to qualify for the free, limited-edition Hacktoberfest t-shirt.

“Maintainers are the backbone of the open-source community and this year, we’re focused more than ever on ensuring maintainers are receiving the love they deserve,” DigitalOcean Senior Community Relations Manager Phoebe Quincy said. “Our maintainer-friendly rules include allowing repos to opt-in to Hacktoberfest, ensuring only accepted pull requests count towards participants’ Hacktoberfest goals, and for the first time ever, enabling maintainers to receive a Hacktoberfest t-shirt without having to submit pull requests.”

Open source maintainers and contributors can join anytime during the month until October 31st. If you maintain a WordPress-related open source project, you can get your project ready to receive contributions by adding the ‘Hacktoberfest’ topic to your repository, tagging issues with the ‘Hacktoberfest’ label, and adding a CONTRIBUTING.md file. Maintainers are also encouraged to select issues that have a well-defined scope and are self-contained. Merging PR’s, adding the ‘hacktoberfest-accepted’ label, and marking ‘invalid’ or ‘spam’ contributions will all count towards engaged maintenership participation.

The REST of the 10 Commandments

One of the core things I've been working on for the past 10 years is APIs — everything from simple APIs that are used by one client to multi-device and multi-purpose APIs. During those years, I've also had the opportunity to work with many third-party APIs like Stripe, Twilio, and others who are less popular and glamorous. Almost all of those APIs were REST-based and unique in some way. 

There are many reasons why REST is so popular. It's simple to understand, it's flexible, it works on any scale, it has a great community and tools built around it. But besides those, I'd also say that a lot of popularity came from the fact that's its oldest rival, SOAP, is just horrible.

The Case for ‘Developer Experience’

A good essay from Jean Yang.

What I mean by developer experience is the sum total of how developers interface with their tools, end-to-end, day-in and day-out. Sure, there’s more focus than ever on how developers use and adopt tools, and there are entire talks and panels devoted to the topic of so-called “DX” — yet large parts of developer experience are still largely ignored. With developers spending less than a third of their time actually writing code, developer experience includes all the other stuff: maintaining code, testing, security issues, addressing incidents, and more. And many of these aspects of developer experience continue getting ignored because they’re complex, they’re messy, and they don’t have “silver bullet” solutions.

She makes the case that DX has perhaps been generally oversimplified and there are categories of tools that have very different DX:

My major revelation was that there are actually two categories of tools — and therefore, two different categories of developer experience needs: abstraction tools (which assume we code in a vacuum) and complexity-exploring tools (which assume we work in complex environments). Most developer experience until now has been solely focused on the former category of abstraction, where there are more straightforward ways to understand good developer experience than the former. 

Reminds me of how Shawn thinks:

It’s time we look beyond the easy questions in developer experience and start addressing the uncomfortable ones.

Direct Link to ArticlePermalink


The post The Case for ‘Developer Experience’ appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

Parameterize Jenkinsfile in MultiBranch Jobs

There is no need to spend time on telling how super useful the MultiBranch Job is in Jenkins. However, there is one drawback; You can define and use only one Jenkinsfile in a given repository which will be the default Jenkinsfile for all scanned branches.

As this may sound complicated, from time to time you may need to use different use Jenkinsfiles in the given repository for different purposes. In this case, your only option is to define different Pipeline Jobs with different Jenkinsfile and branch settings. 

What SREs Can Learn From Facebook’s Largest Outage

Facebook’s October 2021 outage was the type of event that gives SREs nightmares: a series of critical business apps crashed in minutes and remained unavailable for hours, disrupting more than 3.5 billion users around the world and costing about 60 million dollars. As incidents go, this was a pretty big one.

It’s also a pretty big learning opportunity for SREs. The outage is a lesson in how even expertly planned systems can sometimes fail, despite having multiple layers of reliability built-in.

Jekyll doesn’t do components? Liar!

I like the pushback from Katie Kodes here. I’ve said in the past that I don’t think server-side languages haven’t quite nailed “building in components” as well as JavaScript has, but hey, this is a good point:

1. Any basic fragment-of-HTML “component” you can define with JSX in a file and then cross-reference as <MyComponent key="value" />, you can just as easily define with Liquid in a file and cross-reference in Jekyll as {% include MyComponent.html key=value %}.

2. Any basic fragment-of-HTML “layout” you can define with JSX in a file and then cross-reference as <MyLayout>Hello, world</MyLayout>, you can just as easily define with Liquid in a file and then cross-reference in the front matter of a Jekyll template as layout: MyLayout.

Any HTML preprocessor that can do partials with local variables is pretty close to replicating the best of stateless JavaScript components. The line gets even blurrier with stuff like Eleventy Serverless that can build individual pages on the fly by hitting the URL of a cloud function.

Direct Link to ArticlePermalink


The post Jekyll doesn’t do components? Liar! appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

Cloud as an Enabler for Sustainability

Cloud as an Enabler for Sustainability

Sustainability has been a buzzword and rightfully so owing to the accelerated global climate crisis. Corporations worldwide acknowledge the urgent need to act on climate change and have even pledged to set climate targets.

According to Gartner, Sustainability is defined as “An objective that guides decision making by incorporating economic, social & environmental impacts.”

Building a Tennis Trivia App With Next.js and Netlify

Today we will be learning how to build a tennis trivia app using Next.js and Netlify. This technology stack has become my go-to on many projects. It allows for rapid development and easy deployment.

Without further ado let’s jump in!

What we’re using

  • Next.js
  • Netlify
  • TypeScript
  • Tailwind CSS

Why Next.js and Netlify

You may think that this is a simple app that might not require a React framework. The truth is that Next.js gives me a ton of features out of the box that allow me to just start coding the main part of my app. Things like webpack configuration, getServerSideProps, and Netlify’s automatic creation of serverless functions are a few examples.

Netlify also makes deploying a Next.js git repo super easy. More on the deployment a bit later on.

What we’re building

Basically, we are going to build a trivia game that randomly shows you the name of a tennis player and you have to guess what country they are from. It consists of five rounds and keeps a running score of how many you get correct.

The data we need for this application is a list of players along with their country. Initially, I was thinking of querying some live API, but on second thought, decided to just use a local JSON file. I took a snapshot from RapidAPI and have included it in the starter repo.

The final product looks something like this:

You can find the final deployed version on Netlify.

Starter repo tour

If you want to follow along you can clone this repository and then go to the start branch:

git clone git@github.com:brenelz/tennis-trivia.git
cd tennis-trivia
git checkout start

In this starter repo, I went ahead and wrote some boilerplate to get things going. I created a Next.js app using the command npx create-next-app tennis-trivia. I then proceeded to manually change a couple JavaScript files to .ts and .tsx. Surprisingly, Next.js automatically picked up that I wanted to use TypeScript. It was too easy! I also went ahead and configured Tailwind CSS using this article as a guide.

Enough talk, let’s code!

Initial setup

The first step is setting up environment variables. For local development, we do this with a .env.local file. You can copy the .env.sample from the starter repo.

cp .env.sample .env.local

Notice it currently has one value, which is the path of our application. We will use this on the front end of our app, so we must prefix it with NEXT_PUBLIC_.

Finally, let’s use the following commands to install the dependencies and start the dev server: 

npm install
npm run dev

Now we access our application at http://localhost:3000. We should see a fairly empty page with just a headline:

Creating the UI markup

In pages/index.tsx, let’s add the following markup to the existing Home() function:

export default function Home() {
  return (
    <div className="bg-blue-500">
    <div className="max-w-2xl mx-auto text-center py-16 px-4 sm:py-20 sm:px-6 lg:px-8">
      <h2 className="text-3xl font-extrabold text-white sm:text-4xl">
        <span className="block">Tennis Trivia - Next.js Netlify</span>
      </h2>
      <div>
        <p className="mt-4 text-lg leading-6 text-blue-200">
          What country is the following tennis player from?
        </p>
        <h2 className="text-lg font-extrabold text-white my-5">
          Roger Federer
        </h2>

        <form>
          <input
            list="countries"
            type="text"
            className="p-2 outline-none"
            placeholder="Choose Country"
          />
          <datalist id="countries">
            <option>Switzerland</option>
           </datalist>
           <p>
             <button
               className="mt-8 w-full inline-flex items-center justify-center px-5 py-3 border border-transparent text-base font-medium rounded-md text-blue-600 bg-white hover:bg-blue-50 sm:w-auto"
               type="submit"
             >
               Guess
            </button>
          </p>
        </form>

        <p className="mt-4 text-lg leading-6 text-white">
          <strong>Current score:</strong> 0
        </p>
      </div>
    </div>
    </div>
  );

This forms the scaffold for our UI. As you can see, we are using lots of utility classes from Tailwind CSS to make things look a little prettier. We also have a simple autocomplete input and a submit button. This is where you will select the country you think the player is from and then hit the button. Lastly, at the bottom, there is a score that changes based on correct or incorrect answers.

Setting up our data

If you take a look at the data folder, there should be a tennisPlayers.json with all the data we will need for this application. Create a lib folder at the root and, inside of it, create a players.ts file. Remember, the .ts extension is required since is a TypeScript file. Let’s define a type that matches our JSON data..

export type Player = {
  id: number,
  first_name: string,
  last_name: string,
  full_name: string,
  country: string,
  ranking: number,
  movement: string,
  ranking_points: number,
};

This is how we create a type in TypeScript. We have the name of the property on the left, and the type it is on the right. They can be basic types, or even other types themselves.

From here, let’s create specific variables that represent our data:

export const playerData: Player[] = require("../data/tennisPlayers.json");
export const top100Players = playerData.slice(0, 100);

const allCountries = playerData.map((player) => player.country).sort();
export const uniqueCountries = [...Array.from(new Set(allCountries))];

A couple things to note is that we are saying our playerData is an array of Player types. This is denoted by the colon followed by the type. In fact, if we hover over the playerData we can see its type:

In that last line we are getting a unique list of countries to use in our country dropdown. We pass our countries into a JavaScript Set, which gets rid of the duplicate values. We then create an array from it, and spread it into a new array. It may seem unnecessary but this was done to make TypeScript happy.

Believe it or not, that is really all the data we need for our application!

Let’s make our UI dynamic!

All our values are hardcoded currently, but let’s change that. The dynamic pieces are the tennis player’s name, the list of countries, and the score.

Back in pages/index.tsx, let’s modify our getServerSideProps function to create a list of five random players as well as pull in our uniqueCountries variable.

import { Player, uniqueCountries, top100Players } from "../lib/players";
...
export async function getServerSideProps() {
  const randomizedPlayers = top100Players.sort((a, b) => 0.5 - Math.random());
  const players = randomizedPlayers.slice(0, 5);

  return {
    props: {
      players,
      countries: uniqueCountries,
    },
  };
}

Whatever is in the props object we return will be passed to our React component. Let’s use them on our page:

type HomeProps = {
  players: Player[];
  countries: string[];
};

export default function Home({ players, countries }: HomeProps) {
  const player = players[0];
  ...
} 

As you can see, we define another type for our page component. Then we add the HomeProps type to the Home() function. We have again specified that players is an array of the Player type.

Now we can use these props further down in our UI. Replace “Roger Federer” with {player.full_name} (he’s my favorite tennis player by the way). You should be getting nice autocompletion on the player variable as it lists all the property names we have access to because of the types that we defined.

Further down from this, let’s now update the list of countries to this:

<datalist id="countries">
  {countries.map((country, i) => (
    <option key={i}>{country}</option>
  ))}
</datalist>

Now that we have two of the three dynamic pieces in place, we need to tackle the score. Specifically, we need to create a piece of state for the current score.

export default function Home({ players, countries }: HomeProps) {
  const [score, setScore] = useState(0);
  ...
}

Once this is done, replace the 0 with {score} in our UI.

You can now check our progress by going to http://localhost:3000. You can see that every time the page refreshes, we get a new name; and when typing in the input field, it lists all of the available unique countries.

Adding some interactivity

We’ve come a decent way but we need to add some interactivity.

Hooking up the guess button

For this we need to have some way of knowing what country was picked. We do this by adding some more state and attaching it to our input field.

export default function Home({ players, countries }: HomeProps) {
  const [score, setScore] = useState(0);
  const [pickedCountry, setPickedCountry] = useState("");
  ...
  return (
    ...
    <input
      list="countries"
      type="text"
      value={pickedCountry}
      onChange={(e) => setPickedCountry(e.target.value)}
      className="p-2 outline-none"
      placeholder="Choose Country"
    />
   ...
  );
}

Next, let’s add a guessCountry function and attach it to the form submission:

const guessCountry = () => {
  if (player.country.toLowerCase() === pickedCountry.toLowerCase()) {
    setScore(score + 1);
  } else {
    alert(‘incorrect’);
  }
};
...
<form
  onSubmit={(e) => {
    e.preventDefault();
    guessCountry();
  }}
>

All we do is basically compare the current player’s country to the guessed country. Now, when we go back to the app and guess the country right, the score increases as expected.

Adding a status indicator

To make this a bit nicer, we can render some UI depending whether the guess is correct or not.

So, let’s create another piece of state for status, and update the guess country method:

const [status, setStatus] = useState(null);
...
const guessCountry = () => {
  if (player.country.toLowerCase() === pickedCountry.toLowerCase()) {
    setStatus({ status: "correct", country: player.country });
    setScore(score + 1);
  } else {
    setStatus({ status: "incorrect", country: player.country });
  }
};

Then render this UI below the player name:

{status && (
  <div className="mt-4 text-lg leading-6 text-white">
    <p>      
      You are {status.status}. It is {status.country}
    </p>
    <p>
      <button
        autoFocus
        className="outline-none mt-8 w-full inline-flex items-center justify-center px-5 py-3 border border-transparent text-base font-medium rounded-md text-blue-600 bg-white hover:bg-blue-50 sm:w-auto"
      >
        Next Player
      </button>
    </p>
  </div>
)}

Lastly, we want to make sure our input field doesn’t show when we are in a correct or incorrect status. We achieve this by wrapping the form with the following:

{!status && (
  <form>
  ...
  </form>
)}

Now, if we go back to the app and guess the player’s country, we get a nice message with the result of the guess.

Progressing through players

Now probably comes the most challenging part: How do we go from one player to the next?

First thing we need to do is store the currentStep in state so that we can update it with a number from 0 to 4. Then, when it hits 5, we want to show a completed state since the trivia game is over.

Once again, let’s add the following state variables:

const [currentStep, setCurrentStep] = useState(0);
const [playersData, setPlayersData] = useState(players);

…then replace our previous player variable with:

const player = playersData[currentStep];

Next, we create a nextStep function and hook it up to the UI:

const nextStep = () => {
  setPickedCountry("");
  setCurrentStep(currentStep + 1);
  setStatus(null);
};
...
<button
  autoFocus
  onClick={nextStep}
  className="outline-none mt-8 w-full inline-flex items-center justify-center px-5 py-3 border border-transparent text-base font-medium rounded-md text-blue-600 bg-white hover:bg-blue-50 sm:w-auto"
 > 
   Next Player
</button>

Now, when we make a guess and hit the next step button, we’re taken to a new tennis player. Guess again and we see the next, and so on. 

What happens when we hit next on the last player? Right now, we get an error. Let’s fix that by adding a conditional that represents that the game has been completed. This happens when the player variable is undefined.

{player ? (
  <div>
    <p className="mt-4 text-lg leading-6 text-blue-200">
      What country is the following tennis player from?
    </p>
    ...
    <p className="mt-4 text-lg leading-6 text-white">
      <strong>Current score:</strong> {score}
    </p>
  </div>
) : (
  <div>
    <button
      autoFocus
      className="outline-none mt-8 w-full inline-flex items-center justify-center px-5 py-3 border border-transparent text-base font-medium rounded-md text-indigo-600 bg-white hover:bg-indigo-50 sm:w-auto"
      >
      Play Again
    </button>
  </div>
)}

Now we see a nice completed state at the end of the game.

Play again button

We are almost done! For our “Play Again” button we want to reset the state all of the game. We also want to get a new list of players from the server without needing a refresh. We do it like this:

const playAgain = async () => {
  setPickedCountry("");
  setPlayersData([]);
  const response = await fetch(
    process.env.NEXT_PUBLIC_API_URL + "/api/newGame"
  );
  const data = await response.json();
  setPlayersData(data.players);
  setCurrentStep(0);
  setScore(0);
};

<button
  autoFocus
  onClick={playAgain}
  className="outline-none mt-8 w-full inline-flex items-center justify-center px-5 py-3 border border-transparent text-base font-medium rounded-md text-indigo-600 bg-white hover:bg-indigo-50 sm:w-auto"
>
  Play Again
</button>

Notice we are using the environment variable we set up before via the process.env object. We are also updating our playersData by overriding our server state with our client state that we just retrieved.

We haven’t filled out our newGame route yet, but this is easy with Next.js and Netlify serverless functions . We only need to edit the file in pages/api/newGame.ts.

import { NextApiRequest, NextApiResponse } from "next"
import { top100Players } from "../../lib/players";

export default (req: NextApiRequest, res: NextApiResponse) => {
  const randomizedPlayers = top100Players.sort((a, b) => 0.5 - Math.random());
  const top5Players = randomizedPlayers.slice(0, 5);
  res.status(200).json({players: top5Players});
}

This looks much the same as our getServerSideProps because we can reuse our nice helper variables.

If we go back to the app, notice the “Play Again” button works as expected.

Improving focus states

One last thing we can do to improve our user experience is set the focus on the country input field every time the step changes. That’s just a nice touch and convenient for the user. We do this using a ref and a useEffect:

const inputRef = useRef(null);
...
useEffect(() => {
  inputRef?.current?.focus();
}, [currentStep]);

<input
  list="countries"
  type="text"
  value={pickedCountry}
  onChange={(e) => setPickedCountry(e.target.value)}
  ref={inputRef}
  className="p-2 outline-none"
  placeholder="Choose Country"
/>

Now we can navigate much easier just using the Enter key and typing a country.

Deploying to Netlify

You may be wondering how we deploy this thing. Well, using Netlify makes it so simple as it detects a Next.js application out of the box and automatically configures it.

All I did was set up a GitHub repo and connect my GitHub account to my Netlify account. From there, I simply pick a repo to deploy and use all the defaults.

The one thing to note is that you have to add the NEXT_PUBLIC_API_URL environment variable and redeploy for it to take effect.

You can find my final deployed version here.

Also note that you can just hit the “Deploy to Netlify” button on the GitHub repo.

Conclusion

Woohoo, you made it! That was a journey and I hope you learned something about React, Next.js, and Netlify along the way.

I have plans to expand this tennis trivia app to use Supabase in the near future so stay tuned!

If you have any questions/comments feel free to reach out to me on Twitter.


The post Building a Tennis Trivia App With Next.js and Netlify appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

Comparing Google Analytics and Plausible Numbers

I saw this blog post the other day: 58% of Hacker News, Reddit and tech-savvy audiences block Google Analytics. That’s an enticing title to me. I’ve had Google Analytics on this site literally from the day I launched it. While we tend to see some small growth each year, I’m also aware that the ad-blocking usage (and general third-party script blocking) goes up over time. So maybe we have more growth than we can easily visualize in Google Analytics?

The level of Google Analytics blockage varies by industry, audience, the device used and the individual website. In a previous study, I’ve found that less than 10% of visitors block Google Analytics on foodie and lifestyle sites but more than 25% block it on tech-focused sites.

Marko Saric

Marko looked at three days of data on his own website when he had a post trending on both Hacker News and Reddit, and that’s where the 58% came from. Plausible analytics reported 50.9k unique visitors and Google Analytics reported 21.1k. (Google Analytics calls them “Users.”)

I had to try this myself. If we’re literally getting double the traffic Google Analytics says we are, I’d really like to know that. So for the last week, I’ve had Plausible installed on this site (they have a generous unlimited 30-day free trial).

Here’s the Plausible data:

And here’s the Google Analytics data for the same exact period:

It’ll be easier to digest in a table:

MetricPlausibleGoogle Analytics
Unique Visitors973k841k
Pageviews1.4m1.5m
Bounce Rate82%82%
Visit Duration1m 31s1m 24s

So… the picture isn’t exactly clear. On one hand, Plausible reports 15% more unique visitors than Google Analytics. Definitely not double, but more! But then, as far as raw traffic is concerned (which actually matters more to me as a site that has ads), Plausible reports 5% less traffic. So it’s still fairly unclear to me what the real story is.

I do think Plausible is a pretty nice bit of software. Easy to install. Simple and nice charts. Very affordable.

Plausible is also third-party JavaScript

I’m sure less people block Plausible’s JavaScript, as, basically, it’s less-known and not Google. But it’s still third-party JavaScript and just as easily blockable as anything else. It’s not a fundamentally different way to measure traffic.

What is fundamentally different is something like Netlify Analytics, where the data comes from server logs that are not blockable (we’ve mentioned this before). That has its own issues, like the fact that Netlify counts bots and Google Analytics doesn’t. Maybe the best bet is something like server-side Google Analytics? That’s just way more technical debt than I’m ready for. Certainly a lot harder than slapping a script tag on the page.

Multiple sources

It felt weird to have multiple analytics tracking on the site at the same time. If I was doing things like tracking custom events, that would get even weirder. If I was going to continue to do it all client-side, I’d probably reach for something like Analytics which is designed to abstract that. But I prefer the idea of sending the data from the client once, and then if it has to go multiple places, do that server-side. That’s basically the entire premise of Segment, which is expensive, but you can self-host or probably write your own without terribly too much trouble. Just seems smart to me to keep less data going over the wire, and having it be first-party JavaScript.


The post Comparing Google Analytics and Plausible Numbers appeared first on CSS-Tricks. You can support CSS-Tricks by being an MVP Supporter.

How Is 5G Relevant in the Present Day?

As 2021 approached, 5G was predicted to reach around 34% of the global population in the next 4 years. How will 5G revolutionize the present scenario of the market? What are my predictions for a 5G-enabled future? What are the risks associated with 5G? Read this article to know what I expect from the 5G-enabled future.

5G networks are part of a major digital transformation trend that is impacting consumer, public sector, and enterprise spaces. New devices and applications are emerging in the market that takes advantage of the dramatically reduced latency and much higher throughput than 5G offers.  Examples include accelerated adoption of smart cities, smart factories, next-generation in-store experiences, healthcare services autonomous cars, and much more. It’s an exciting time.  By now, you are familiar with the excitement surrounding the 5G revolution.

Spring Cloud Gateway :  Resource Server With Keycloak RBAC

In this article, we will be exploring how we can integrate a resource server with an API gateway that is integrated with Keycloak and that enables role-based access control (RBAC).

Introduction

In my previous article “Spring Cloud Gateway Keycloak OAuth2 OIDC Integration,” I have shown how we can integrate Keycloak with Spring Cloud Gateway. Now in this article, we will extend this further to integrate a resource server, such that a client (e.g browser) can access a resource only when he has the correct role to access the resource on the server. This is a continuation of the aforementioned article, so I recommend reading it.

13 Free User Management Plugins for WordPress (2021)

Are you looking for the best user management plugins for WordPress?

User management plugins let you more easily register, edit, and manage users on your WordPress website.

In this article, we’ll share our favorite user management plugins that you can use on your WordPress site.

13 Free User Management Plugins for WordPress Compared

Why Do You Need a User Management Plugin in WordPress?

WordPress user management plugins make it easy to manage and register new users on your WordPress website.

There is built-in functionality to manage user registrations, but it’s quite limited and doesn’t give you much control over your users.

With a user registration plugin, you can easily manage your users in bulk, customize user roles, create custom login and registration forms, and more.

If you’re running a multisite network, online course, multi-author blog, or membership site, then this gives you more flexibility and control over your users.

That being said, let’s take a look at the best user management plugins for WordPress.

1. Members

Members

Members is a free user management plugin used by over 200,000 sites that lets you easily create and manage user roles and permissions in WordPress.

You can easily set permissions and restrict content on your website without having to code or hire a developer.

The advanced role editor lets you create, delete, and customize roles and capabilities for any user through the easy to use interface. You can even assign multiple roles to different users.

Edit user role capabilities

It also integrates with other popular plugins, including MemberPress, to help you build a paid membership site.

For more details, see our beginner’s guide to WordPress user roles and permissions.

2. WPForms

WPForms

WPForms is the best contact form plugin for WordPress used by over 4 million websites.

It’s very easy to use and lets you build contact forms and other forms with the drag and drop builder.

The free version of the plugin has simple contact form features like spam protection, basic form fields, email notifications, and simple user management.

If you want to create custom user registration forms, then you’ll need the pro version that comes with the User Registration Form addon.

You can use this addon to build custom user registration and login forms. This lets new users create an account on your WordPress website.

The registration forms are completely customizable. You can change form fields like the username, bio, assigned user roles, and much more.

WPForms registration form

For spam protection, you can manually approve new users or require them to confirm their profile by clicking a link in their email.

If you have an email list, then you can integrate WPForms with the most popular email marketing services to automatically add users to your email list.

3. MemberPress

MemberPress

MemberPress is the best WordPress membership plugin in the market.

It’s very easy to use and can help you quickly build a membership site or online course in WordPress.

After you activate and set up the plugin, you can turn on user registration in a couple of clicks. To embed new user registration forms into your website, you can use the custom shortcodes.

Beyond new user registration, you can easily view and manage your existing users and even edit their profiles.

Plus, it supports all kinds of integrations with the most popular WordPress plugins. For example, the WooCommerce integration to help you create a members-only online store, add WooCommerce registration forms, send new user emails, and more.

4. Formidable Forms

Formidable Forms

Formidable Forms is one of the most advanced WordPress form builders in the market, used by more than 300,000 businesses.

You can use the drag and drop builder to easily create advanced forms like quizzes, payment forms, job board listings, surveys, online calculators, and much more.

Both the Business and Elite plans allow you to add advanced user registration forms to your WordPress site. Your users can register and edit their profiles all from the front end of your website.

Formidable Forms user registration forms

There are all kinds of advanced options like user nickname fields, custom password reset pages, field auto population with user data, and more.

You’ll also find advanced integrations to register WooCommerce users or automatically add users to your email newsletter, CRM, and more.

5. WP User Manager

WP User Manager

WP User Manager is a free user registration and profile builder plugin. It has features like custom user registration and customizable user profiles, login form, password recovery, and more.

Plus, you can create custom front end login forms, let users create custom avatars, display users in a directory, and much more.

If you’re building a community based website, then this plugin can help you easily manage all of your members.

6. LoginWP

LoginWP

LoginWP (formerly Peter’s Login Redirect) is a free plugin that lets you automatically redirect users after they log in to your website. You can redirect users based on their username, user role, capabilities, and more.

This plugin makes it easy to redirect users to a custom welcome or thank you page after they successfully register on your website.

It’s very easy to use and only takes a couple of clicks to set up the redirects. For step-by-step instructions, see our guide on how to redirect users after a successful login.

7. User Switching

User Switching

User Switching is a great free plugin that lets you quickly switch to different user accounts.

Instead of having to log out and log in to different user profiles, you can do it in one click from your WordPress dashboard.

This can be useful for testing WordPress sites, where you regularly need to log out and switch between different accounts.

8. Comment Moderation Role

Comment Moderation Role

Comment Moderation Role is a simple and free plugin that lets you easily create a comment moderation user role in WordPress.

This lets you keep you WordPress website secure while creating a role that only allows for comment moderation. Every other part of the WordPress dashboard will be hidden.

User comment moderator dashboard

For more details, see our guide on how to allow blog users to moderate comments in WordPress.

9. Simple History

Simple History

Simple History is a free WordPress plugin that lets you monitor the activity of your WordPress users. It shows you actions your users have taken on your WordPress site, which helps you spot any errors or security issues faster.

You can choose whether you want your user activity log to display, and you can show the user history for the last 30 or 60 days.

For more details, see our guide on how to monitor user activity in WordPress with security audit logs.

Alternative: WP Activity Log provides detailed user tracking and real-time reports.

10. SeedProd

SeedProd

SeedProd is the best drag and drop page builder for WordPress used by over 1 million websites. It lets you create completely custom pages in WordPress without writing a line of code.

The plugin has a beginner-friendly drag and drop builder, a page template collection, and pre-design sections to make the page building process quick and easy.

Plus, it has a WPForms integration, so you can build a registration form with WPForms and customize it with SeedProd.

SeedProd registration form

The free version of SeedProd can be used to customize your user registration page.

However, the premium version of the plugin comes with over 100 professionally designed templates, additional content blocks, integrations, subscriber management features, and more.

11. Bulk Delete

Bulk Delete

Bulk Delete is a useful free plugin that lets you bulk delete users on your site that have a specific role or other criteria. For example, you can delete users that haven’t logged in for a specific amount of time.

Instead of selecting users manually, this plugin lets you bulk delete users in a couple of clicks.

You have complete control over the filters you want to use to delete users, like the number of posts, last login date, user role, and more.

12. Hide Admin Bar Based on User Roles

Hide Admin Bar Based on User Roles

Hide Admin Bar Based on User Roles is a simple plugin that does exactly what the name suggests and lets you hide your WordPress admin bar for specific user roles.

Hiding the admin bar can help to improve the user experience for some users. For example, you might want to hide the admin bar on the front-end of your website for subscribers, or for users who aren’t able to edit posts or pages.

For more details, see our guide on how to disable WordPress admin bar for all users except administrators.

13. Import and Export Users and Customers

Import and Export Users and Customers

Import and Export Users and Customers is a free plugin that helps you easily export and import WordPress users. This can be very useful if you’re merging multiple sites and want to add all your users to the new site automatically.

It can also be helpful if you want to import your existing customer or user information to your CRM or email list. It’s very easy to use and can help you import or export user data in a couple of clicks.

For more details, see our guide on how to easily import and export your WordPress users.

We hope this article helped you find the best free user management plugins for your WordPress site. You may also want to see our guide on how to choose the best WordPress hosting and our expert picks of the best business phone services for small businesses.

If you liked this article, then please subscribe to our YouTube Channel for WordPress video tutorials. You can also find us on Twitter and Facebook.

The post 13 Free User Management Plugins for WordPress (2021) appeared first on WPBeginner.