Never develop on a live site. A local copy lets you break things, read every error and reset in seconds, without visitors seeing anything. This lesson sets up a local WordPress site and turns on the debugging settings you will rely on for the rest of the course.
What a local WordPress needs
WordPress needs three things to run:
- A web server, such as Apache or Nginx.
- PHP, version 8.1 or newer for this course.
- A MySQL or MariaDB database.
You can install these by hand, but a local development tool does it for you and adds conveniences such as one-click sites and HTTPS. Three common choices:
| Tool | How it works | Good for |
|---|---|---|
| wp-env | Runs WordPress in Docker containers, configured by a JSON file in your project | Plugin and theme projects that share a setup with a team |
| Laragon (Windows) | A lightweight local server stack with Apache or Nginx, PHP and MySQL | Fast Windows setups with many sites |
| Local | A desktop app that creates and manages WordPress sites | A graphical tool on Windows, macOS or Linux |
Any of them works for this course. Pick one and move on.
Option 1: wp-env
wp-env is the WordPress project's own tool. It needs Docker and Node.js installed. From your plugin folder, install it and start a site:
npm install -g @wordpress/env
cd my-plugin
wp-env start
The first start downloads WordPress and the containers, so it takes a few minutes. When it finishes, the site is at http://localhost:8888 and the admin is at http://localhost:8888/wp-admin with the username admin and password password.
If you run wp-env start inside a folder that contains a plugin, wp-env mounts it and activates it automatically. For more control, add a .wp-env.json file to the project:
{
"core": null,
"phpVersion": "8.2",
"plugins": [ "." ],
"config": {
"WP_DEBUG": true,
"SCRIPT_DEBUG": true
}
}
"core": null uses the latest WordPress release, and "plugins": [ "." ] loads the current folder as a plugin. wp-env also gives you WP-CLI inside the container:
wp-env run cli wp plugin list
wp-env stop
Option 2: Laragon or Local
With Laragon, start the stack, then use the menu to create a new WordPress site (Quick app, then WordPress). Laragon downloads WordPress, creates a database and gives the site a local domain such as http://myproject.test.
With Local, choose to add a site, give it a name and accept the default environment. Local creates the site and a database and shows you the admin login.
In both cases your site is a normal folder on disk. Find its wp-content/plugins folder: that is where your project plugin will live.
Create your project plugin
Throughout the course you will add code to one plugin. Create the folder wp-content/plugins/myplugin with a file called myplugin.php:
<?php
/**
* Plugin Name: My Plugin
* Description: Course project for the WordPress Development Complete Course.
* Version: 0.1.0
* Requires PHP: 8.1
* Text Domain: myplugin
*/
defined( 'ABSPATH' ) || exit;
The comment block is the plugin header. WordPress reads it to list the plugin on the Plugins screen. The defined( 'ABSPATH' ) || exit; line stops the file running if someone requests it directly in a browser, because ABSPATH is only defined when WordPress has loaded.
Go to Plugins in the admin and activate My Plugin. Nothing visible happens yet, which is correct.
Turn on debugging
By default, WordPress hides PHP notices and warnings. That is right for a live site and wrong for development. Open wp-config.php in the site root and find the line define( 'WP_DEBUG', false );. Replace it with:
// wp-config.php, above the line that says "That's all, stop editing!"
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
define( 'SCRIPT_DEBUG', true );
define( 'WP_ENVIRONMENT_TYPE', 'local' );
What each setting does:
| Constant | Effect |
|---|---|
WP_DEBUG | Turns on reporting of all PHP errors, notices and deprecation messages |
WP_DEBUG_LOG | Writes them to wp-content/debug.log |
WP_DEBUG_DISPLAY | Set to false so errors go to the log, not into the page HTML |
SCRIPT_DEBUG | Loads the unminified versions of core JavaScript and CSS |
WP_ENVIRONMENT_TYPE | Tells code which environment it runs in: local, development, staging or production |
Never enable WP_DEBUG_DISPLAY on a live site. Error messages can reveal file paths, queries and other details an attacker can use.
Logging rather than displaying keeps pages readable and catches errors that happen during redirects or AJAX requests, where you would never see on-screen output.
Read the debug log
Prove the log works. Add a deliberate mistake to your plugin file:
// wp-content/plugins/myplugin/myplugin.php, temporarily
error_log( 'myplugin loaded' );
echo $myplugin_undefined;
Load any page, then look at the end of the log:
tail -n 20 wp-content/debug.log
You will see your message and a warning about the undefined variable, with the file and line number. Remove both lines when you are done.
Keep the log open in a second terminal with tail -f wp-content/debug.log while you work. New errors appear the moment they happen.
Use the environment type in code
Code can check the environment with wp_get_environment_type(), which returns the value of WP_ENVIRONMENT_TYPE or production if it is not set:
// wp-content/plugins/myplugin/myplugin.php
if ( 'local' === wp_get_environment_type() ) {
// Development-only behaviour, such as extra logging.
}
Use this for small differences, such as disabling an outgoing email integration locally. Do not use it to hide bugs.
Install a few developer tools
Two tools make WordPress development much easier:
- WP-CLI, the command-line interface for WordPress. It is built into
wp-envand bundled with many local tools. You will use it throughout the course and learn it properly in the WP-CLI lesson. - Query Monitor, a free plugin from the WordPress.org directory that shows queries, hooks, HTTP requests and PHP errors for each page. You will use it in the debugging and performance lessons.
Check WP-CLI works from your site folder:
wp --info
wp core version
Summary
- Develop locally, never on a live site.
- wp-env, Laragon and Local all give you a working server, PHP and database.
- Keep your course code in one plugin with a plugin header and the
ABSPATHcheck. - Turn on
WP_DEBUGandWP_DEBUG_LOG, keepWP_DEBUG_DISPLAYoff, and readwp-content/debug.log. - Set
WP_ENVIRONMENT_TYPEand read it withwp_get_environment_type().
In the next lesson you will look inside the WordPress folders and wp-config.php.