---
title: Custom DDev Command
date: 2026-03-27T09:13:00-04:00
author: cc_admin
canonical_url: "https://caffeinecreations.ca/blog/custom-ddev-command/"
section: Blog
---
![Custom ddev lp](https://caffeinecreations.ca/uploads/blog/_1920x660_crop_center-center_none_ns/custom-ddev-lp1.png)

- [Web Development](https://caffeinecreations.ca/blog/category/web-development/), [Code](https://caffeinecreations.ca/blog/category/code/)

# Custom DDev Command

A while ago I was getting slightly annoyed having to type two commands everytime I opened a project. `ddev launch` opens your local site in the browser, and `ddev launch access` opens the Craft CMS control panel. I wanted a simpler better way.

And what I ended up with is a file saved at `.ddev/commands/host/lp`. Once in place, you can run `ddev lp` to open both the site and control panel, or pass an optional path like `ddev lp contact` to open a specific page instead of the homepage.

The script does three things: it reads your `CRAFT_CP_TRIGGER` value from `.env` to build the correct control panel URL, accepts an optional path argument to open a specific page on the frontend, and handles browser launching cross-platform across macOS, Windows, and Linux.  
  
Copy below and save it to that directory. You may need to restart DDEV for the new command to be recognized.

This should work out of the box for Craft CMS sites with `CRAFT_CP_TRIGGER` set in your `.env` file, but can easily be modified for other CMSes.

```
<button class="absolute z-10 flex items-center justify-center w-8 h-8 -translate-y-1/2  -right-4 -top-4" clipboard="" title="Copy to Clipboard" to="" type="button" x-clipboard.raw="#!/usr/bin/env bash
## Description: Launch Craft CMS Control Panel and site homepage (reads CRAFT_CP_TRIGGER from .env)
## Usage: lp [path]
## Example: "ddev lp" or "ddev lp about" or "ddev lp styleguide"

# Handle help flag
if [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
  echo "Launch a browser with the Craft CMS Control Panel and site homepage"
  echo ""
  echo "Usage:"
  echo "  ddev lp [path]"
  echo ""
  echo "Examples:"
  echo "  \"ddev lp\" - Opens Control Panel and homepage"
  echo "  \"ddev lp about\" - Opens Control Panel and /about"
  echo ""
  echo "The Control Panel URL is determined by the CRAFT_CP_TRIGGER value in your .env file"
  exit 0
fi

# CP_TRIGGER=""

if [ -f ".env" ]; then
  ENV_CP_TRIGGER=$(grep '^CRAFT_CP_TRIGGER=' .env | cut -d '=' -f2 | tr -d '"')
  if [ -n "$ENV_CP_TRIGGER" ]; then
    CP_TRIGGER="$ENV_CP_TRIGGER"
  fi
fi

# Get optional path argument
CUSTOM_PATH="${1}"

# Build URLs
URL="https://${DDEV_HOSTNAME}/${CP_TRIGGER}"

# Handle custom path if provided
if [ -n "$CUSTOM_PATH" ]; then
  # Remove leading slash if present (we'll add it)
  CUSTOM_PATH="${CUSTOM_PATH#/}"
  HOME_URL="https://${DDEV_HOSTNAME}/${CUSTOM_PATH}"
else
  HOME_URL="https://${DDEV_HOSTNAME}/"
fi

# Function to open URL in browser (cross-platform)
open_browser() {
  local url="$1"
  if command -v start > /dev/null 2>&1; then
    # Windows (Git Bash, MSYS2, Cygwin)
    start "$url" 2>/dev/null || cmd.exe /c start "$url"
  elif command -v open > /dev/null 2>&1; then
    # macOS
    open "$url"
  elif command -v xdg-open > /dev/null 2>&1; then
    # Linux
    xdg-open "$url"
  else
    echo "Could not find browser launch command."
    echo "Please open your browser and navigate to: $url"
    return 1
  fi
}

echo "Launching Control Panel: $URL"
open_browser "$URL"

echo "Launching Homepage: $HOME_URL"
open_browser "$HOME_URL"" x-data="">
	<svg class="h-5 w-5" viewbox="0 0 64 64" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
  <rect fill="#f3f4f6" height="53" rx="3" width="41" x="7" y="2"></rect>
  <rect fill="#f3f4f6" height="51" rx="3" width="39" x="19" y="11"></rect>
  <path d="M53.98 9.143h-3.97c-.082 0-.155.028-.232.047V5.023C49.778 2.253 47.473 0 44.64 0H10.217C7.384 0 5.08 2.253 5.08 5.023v46.843c0 2.77 2.305 5.023 5.138 5.023h6.037v2.268c0 2.67 2.216 4.843 4.941 4.843H53.98c2.725 0 4.942-2.173 4.942-4.843v-45.17c0-2.671-2.217-4.844-4.942-4.844zM7.11 51.866V5.023c0-1.649 1.394-2.991 3.106-2.991H44.64c1.712 0 3.106 1.342 3.106 2.99v46.844c0 1.649-1.394 2.991-3.106 2.991H10.217c-1.712 0-3.106-1.342-3.106-2.99zm49.778 7.29c0 1.551-1.306 2.812-2.91 2.812H21.195c-1.604 0-2.91-1.26-2.91-2.811v-2.268H44.64c2.833 0 5.138-2.253 5.138-5.023V11.128c.077.018.15.047.233.047h3.968c1.604 0 2.91 1.26 2.91 2.811v45.17z"></path>
  <path d="M38.603 13.206H16.254a1.015 1.015 0 1 0 0 2.032h22.35a1.015 1.015 0 1 0 0-2.032zM38.603 21.333H16.254a1.015 1.015 0 1 0 0 2.032h22.35a1.015 1.015 0 1 0 0-2.032zM38.603 29.46H16.254a1.015 1.015 0 1 0 0 2.032h22.35a1.015 1.015 0 1 0 0-2.032zM28.444 37.587h-12.19a1.015 1.015 0 1 0 0 2.032h12.19a1.015 1.015 0 1 0 0-2.032z"></path>
</svg>
<div class="sr-only">Copy to clipboard</div></button>```html
#!/usr/bin/env bash
## Description: Launch Craft CMS Control Panel and site homepage (reads CRAFT_CP_TRIGGER from .env)
## Usage: lp [path]
## Example: "ddev lp" or "ddev lp about" or "ddev lp styleguide"

# Handle help flag
if [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
  echo "Launch a browser with the Craft CMS Control Panel and site homepage"
  echo ""
  echo "Usage:"
  echo "  ddev lp [path]"
  echo ""
  echo "Examples:"
  echo "  \"ddev lp\" - Opens Control Panel and homepage"
  echo "  \"ddev lp about\" - Opens Control Panel and /about"
  echo ""
  echo "The Control Panel URL is determined by the CRAFT_CP_TRIGGER value in your .env file"
  exit 0
fi

# CP_TRIGGER=""

if [ -f ".env" ]; then
  ENV_CP_TRIGGER=$(grep '^CRAFT_CP_TRIGGER=' .env | cut -d '=' -f2 | tr -d '"')
  if [ -n "$ENV_CP_TRIGGER" ]; then
    CP_TRIGGER="$ENV_CP_TRIGGER"
  fi
fi

# Get optional path argument
CUSTOM_PATH="${1}"

# Build URLs
URL="https://${DDEV_HOSTNAME}/${CP_TRIGGER}"

# Handle custom path if provided
if [ -n "$CUSTOM_PATH" ]; then
  # Remove leading slash if present (we'll add it)
  CUSTOM_PATH="${CUSTOM_PATH#/}"
  HOME_URL="https://${DDEV_HOSTNAME}/${CUSTOM_PATH}"
else
  HOME_URL="https://${DDEV_HOSTNAME}/"
fi

# Function to open URL in browser (cross-platform)
open_browser() {
  local url="$1"
  if command -v start > /dev/null 2>&1; then
    # Windows (Git Bash, MSYS2, Cygwin)
    start "$url" 2>/dev/null || cmd.exe /c start "$url"
  elif command -v open > /dev/null 2>&1; then
    # macOS
    open "$url"
  elif command -v xdg-open > /dev/null 2>&1; then
    # Linux
    xdg-open "$url"
  else
    echo "Could not find browser launch command."
    echo "Please open your browser and navigate to: $url"
    return 1
  fi
}

echo "Launching Control Panel: $URL"
open_browser "$URL"

echo "Launching Homepage: $HOME_URL"
open_browser "$HOME_URL"
```
```

A few examples to get you started:

- `ddev lp` — opens the control panel and homepage
- `ddev lp about` — opens the control panel and `/about`
- `ddev lp contact` — opens the control panel and `/contact`

This is just one example of how powerful DDEV's custom command system is. If you find yourself typing the same commands repeatedly, it's worth checking out the [DDEV custom commands docs](https://ddev.readthedocs.io/en/stable/users/extend/custom-commands/) to see what else you can automate.

[![Boilerplates to Accelerate Development Thumbnail](https://caffeinecreations.ca/uploads/blog/_680x320_crop_center-center_65_none_ns/boilerplates.png)### Boilerplates to Accelerate Development](https://caffeinecreations.ca/blog/boilerplates-to-accelerate-development/)

[![Dark Mode with AlpineJs and Tailwind Thumbnail](https://caffeinecreations.ca/uploads/blog/_680x320_crop_center-center_65_none_ns/dark-mode-heroa.jpg)### Dark Mode with AlpineJs and Tailwind](https://caffeinecreations.ca/blog/dark-mode-with-alpinejs-and-tailwind/)

[![Adding Glossary Tooltips to Redactor Fields Using Craft CMS and Tippy.js Thumbnail](https://caffeinecreations.ca/uploads/blog/_680x320_crop_center-center_65_none_ns/tooltips.jpg)### Adding Glossary Tooltips to Redactor Fields Using Craft CMS and Tippy.js](https://caffeinecreations.ca/blog/adding-glossary-tooltips-to-redactor-fields-using-craft-cms-and-tippy-js/)
