<p>My guess is that you're using the <code>@web</code> <a href="https://craftcms.com/docs/4.x/config/#aliases" rel="nofollow noreferrer">alias</a> for your sites' &quot;Base URL&quot; setting. Unless explicitly declared in your project, this alias will resolve to an empty string for console requests, since Craft isn't able to deduce what your host name is in that environment.</p>
<p>To fix this issue, you should explicitly declare the <code>@web</code> alias by adding an environment variable <code>CRAFT_WEB_URL</code>, e.g. in your <code>.env</code> file:</p>
<pre><code>CRAFT_WEB_URL=http://localhost:3000
</code></pre>
<p>Alternatively, you can override the <code>@web</code> alias via your <code>config/general.php</code> config file:</p>
<pre class="lang-php prettyprint-override"><code>use craft\helpers\App;

return [
    'aliases' =&gt; [
        '@web' =&gt; App::env('BASE_SITE_URL'),
    ],
];
</code></pre>
<p>In addition to (likely) solving the relevant issue, explicitly setting the <code>@web</code> alias to a fully qualified URL is considered a good practice as it prevents a variety of security issues.</p>

CC BY-SA 4.0
2023-03-23T15:13:56.600Z
2023-03-23T15:13:56.600Z
Mats Mikkel Rummelhoff
<p>In an e-mail template in a custom plugin I want to render a link to an entry. This needs to be an absolute URL.</p>
<p>I need this to work both when triggering the action from the control panel, and when running it as a console command. This means I cannot hard code the base URL in front of the <code>{{ item.url }}</code> part.</p>
<p>When triggering the action from the control panel, this part of the template</p>
<pre><code>&lt;a href=&quot;{{ item.url }}&quot;&gt;Read more&lt;/a&gt;
</code></pre>
<p>renders the following:</p>
<pre><code>&lt;a href=&quot;http://localhost:3000/posts/slug-of-post&quot;&gt;Read more&lt;/a&gt;
</code></pre>
<p>However, when running from the console, it renders the following:</p>
<pre><code>&lt;a href=&quot;/posts/slug-of-post&quot;&gt;Read more&lt;/a&gt;
</code></pre>
<hr />
<p>I've tried to isolate the getUrl() for easier testing. This also gives relative URLs.</p>
<pre><code>use craft\console\Controller;

public static function actionTestMe(): int
{
    $entry = \craft\elements\Entry::find()
        -&gt;site('site')
        -&gt;section('posts')
        -&gt;one();

    echo $entry-&gt;getUrl(); // Output: /posts/slug-of-post
    (...)
}
</code></pre>

CC BY-SA 4.0
2023-03-23T12:48:19.017Z
What is your site's "Base URL" setting set to in the CP?
Mats Mikkel Rummelhoff
CC BY-SA 4.0
2023-03-23T12:52:38.310Z
This is a multi-site project, but the Primary site's Base URL is `http://localhost:3000/`. For what it's worth adding `echo Craft::$app->sites->currentSite->baseUrl;` in my test action also gives `http://localhost:3000/`.
PWL
<plugin-development><craft4>
Entry url in console action doesn't return absolute URL
# Entry url in console action doesn't return absolute URL

(Asked by: username_0 on 2023-03-23)

In an e-mail template in a custom plugin I want to render a link to an entry. This needs to be an absolute URL.
I need this to work both when triggering the action from the control panel, and when running it as a console command. This means I cannot hard code the base URL in front of the {{ item.url }} part.
When triggering the action from the control panel, this part of the template
Read more

renders the following:
Read more

However, when running from the console, it renders the following:
Read more


I've tried to isolate the getUrl() for easier testing. This also gives relative URLs.
use craft\console\Controller;

public static function actionTestMe(): int
{
    $entry = \craft\elements\Entry::find()
        ->site('site')
        ->section('posts')
        ->one();

    echo $entry->getUrl(); // Output: /posts/slug-of-post
    (...)
}

**Tags:** plugin-development, craft4
> **Comments:**
> **username_1**: What is your site's "Base URL" setting set to in the CP?  
> **username_0**: This is a multi-site project, but the Primary site's Base URL is `http://localhost:3000/`. For what it's worth adding `echo Craft::$app->sites->currentSite->baseUrl;` in my test action also gives `http://localhost:3000/`.  

---

## 1 answers

### Answer by username_1 on 2023-03-23. Score: 1

My guess is that you're using the @web alias for your sites' "Base URL" setting. Unless explicitly declared in your project, this alias will resolve to an empty string for console requests, since Craft isn't able to deduce what your host name is in that environment.
To fix this issue, you should explicitly declare the @web alias by adding an environment variable CRAFT_WEB_URL, e.g. in your .env file:
CRAFT_WEB_URL=http://localhost:3000

Alternatively, you can override the @web alias via your config/general.php config file:
use craft\helpers\App;

return [
    'aliases' => [
        '@web' => App::env('BASE_SITE_URL'),
    ],
];

In addition to (likely) solving the relevant issue, explicitly setting the @web alias to a fully qualified URL is considered a good practice as it prevents a variety of security issues.


---

