21

I want to install laravel in shared hosting and I followed the steps here https://stackoverflow.com/a/28449523 but my asset path doesn't include the public directory

Instead of this

<link href='http://example.com/public/assets/css/style.css' type='text/css' media='all' />

I'm getting this

<link href='http://example.com/assets/css/style.css' type='text/css' media='all' />

How do I change the directory of the asset folder(add public to assets) without changing any core classes?

Community
  • 1
  • 1
user3407278
  • 1,233
  • 5
  • 16
  • 32
  • The tutorial you followed is for removing the Public segment. If you have really done it, you have removed, Public, haven't you? If your host has cpanel, all you need is to click on Softaculous and installation is automatic, it will install it with the public segment in by default – patricio Sep 27 '15 at 17:23
  • but my asset path doesn't include the public folder I want it to be included when using the asset() function. – user3407278 Sep 27 '15 at 17:26
  • It seems that you cannot achieve it without changing core classes. – Zahan Safallwa Sep 29 '15 at 07:37
  • try to change `.htaccess` file – Miron Dec 16 '15 at 14:14

4 Answers4

34

Add ASSET_URL=public in your .env file and run php artisan config:cache

Abid_niazi_15
  • 825
  • 8
  • 6
19

For the latest version of Laravel - Laravel 5.8, there is a key in config/app.php with name asset_url. The value of this key determines the value that the asset() method returns. Normally, you should set the value of this key to the base url of your website if all your asset folders are in the default location (this default location is the public folder under the root directory of your Laravel installation).

For example if your website url is "https://www.example.com" and you want to access the asset path public/assets/css/sample.css under the root folder, set the asset_url in config/app.php like this:

'asset_url' => env('ASSET_URL', 'https://www.example.com'),

and use the asset function like this:

asset('assets/css/sample.css')

Thereafter, reconfigure your cache by running this within your laravel installation folder:

php artisan config:cache

This will update the bootstrap/cache/config.php file. If you check your browser, the generated url for your asset would be "https://www.example.com/assets/css/sample.css".

One way you can have a valid url like: "https://www.example.com/public/assets/css/sample.css" is by creating another folder named public inside your already existing public folder - which is non-intuitive for me. However, if you do this, then you have to include this path when using the asset function:

asset('public/assets/css/sample.css')
miken32
  • 42,008
  • 16
  • 111
  • 154
Udo E.
  • 2,665
  • 2
  • 21
  • 33
7

Before Laravel 5.7.14

Take a look at Illuminate\Routing\UrlGenerator class and its asset($path, $secure = null) method. This class is being put to container by url key. What you can do is:

  1. Add your own class, extending UrlGenerator;
  2. Add asset($path, $secure = null) method to your own class, making it return whatever you need;
  3. Create a service provider and register it in config/app.php;
  4. In your service provider's register() method, bind your new class to the container by url key.

This way, you don't touch core files at all and your Laravel application is still update friendly.

Update for Laravel 5.7.14 and later

As other answers state, there is the ASSET_URL .env option, which makes it much easier to change the public path. Laravel introduced it in Laravel 5.7.14, which was released about 3 years after my original answer.

Robo Robok
  • 21,132
  • 17
  • 68
  • 126
  • Sorry, What do you mean by binding the new class to the container by url key? how do I do that? And can I do that at the serviceProvider instead of creating a new one? – SpaceDogCS Nov 14 '18 at 04:04
  • This can be done easily by defining ASSET_URL in .env – sabbir ahmed May 13 '20 at 06:47
  • `ASSET_URL` was introduced in Laravel 5.7.14, released in late 2018. The question was asked and answered by me in 2015. I'm gonna update the answer, as many people just look at the selected answer. – Robo Robok May 13 '20 at 09:18
  • @RoboRobok the ASSET_URL is not working if have admin panel URL for e.g www.example.com/admin – Nileshsinh Rathod Jan 20 '21 at 07:03
4

A relatively easier hack is to add the folder in the return value of the asset() function inside \vendor\laravel\framework\src\Illuminate\Routing\UrlGenerator.php

public function asset($path, $secure = null)
{
    if ($this->isValidUrl($path)) {


        return $path;
    }

    // Once we get the root URL, we will check to see if it contains an index.php
    // file in the paths. If it does, we will remove it since it is not needed
    // for asset paths, but only for routes to endpoints in the application.
    $root = $this->assetRoot
                ? $this->assetRoot
                : $this->formatRoot($this->formatScheme($secure));

    // Following 2 lines were added
    if($_SERVER['REMOTE_ADDR'] != '127.0.0.1')
        $root .= '/public';

    return $this->removeIndex($root).'/'.trim($path, '/');
}

Note here that I have added public to the return value based on a condition. So that can be done as well.

Dibyendu Mitra Roy
  • 1,604
  • 22
  • 20