I've managed to install drupal 8 using composer and following script:

composer create-project drupal-composer/drupal-project:8.x-dev my_site_name_dir --stability dev --no-interaction

I decided to use composer since it seems to be the new way and you get all the dependencies with it.

But the structure is different then installing drupal by downloading it to the server. And that's my problem.

I'm using shared hosting and before composer everything landed in the folder public_html. But with composer there's a folder called web inside public_html that holds drupal itself (or at least it seems that way to me). So instead of having a url like www.mydomain.com I end up with www.mydomain.com/web to reach the site.

My question is how do I do to hide /web from the url? Or do I do something when installing via composer?

I've done a temporary solution that hides /web just from the frontpage. Had to create a new .htaccess in public_html which included following:

RewriteRule ^$ web/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /$1 [L]

But as soon as you click on a different page the /web is there again.

Any hints or of course answers are most welcome.

Thanks //Tobias

  • You could run the create in the web root itself, and then update the apache conf to point to /web/ instead of /public_html/ as the docroot. But I am guessing that with this level of hosting, you won't have that access.
    – Kevin
    Jun 15, 2017 at 12:39
  • Thanks @Kevin for your thougts and hints. But as you say I'm not sure I have that access to apache but I'm looking more thoroughly in cpanel to try to find the right way there. What do you think of changing the thought of using redirect instead of rewrite? Is that another way to do this? Once again, thanks for your comment :) Jun 20, 2017 at 7:28

4 Answers 4


Me and my collegue managed to find a working solution.

In our public_html folder we created a .htacess file with the following lines.

RewriteRule ^$ web/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ web/$1 [L] 

We edited the .htaccess file in ~user/public_html/web.

# Modify the RewriteBase if you are using Drupal in a subdirectory or in a
# VirtualDocumentRoot and the rewrite rules are not working properly.
# For example if your site is at http://example.com/drupal uncomment and
# modify the following line: 
RewriteBase /web

In the ~/user/public_html/web/sites/default/settings.php file, we added this code at the bottom.

if (isset($GLOBALS['request']) and
'/web/index.php' === $GLOBALS['request']->server->get('SCRIPT_NAME')) {
$GLOBALS['request']->server->set('SCRIPT_NAME', '/index.php');

We also changed trusted_host_patterns setting as well.

# will allow the site to run off of all variants of example.com and
# example.org, with all the sub-domains included. 

$settings['trusted_host_patterns'] = array(

As I said, this is most likely not the correct way to do it, but it worked for us.


We're currently in a similar boat. We have dedicated hosting, and we're looking to start development of Drupal 8 sites with composers as a way to manage sites.

We took a different approach, we created a directory and adding therein the core, modules, and theme files. Then made a symlink between those files and the public_html folder. It seems to work fine, but, like you, I am not sure what the best practices.

FYI: Here's how we created the symlink:

  1. mv public_html examplesite
  2. ln -s public_html examplesite/webfiles

That seemed to make it work for us.

Edit: I just ran across an article immediately after writing this. It says moving the files out of docroot adds additional security to your site. So, what we did, with the symlink, might be considered the better option.


  • Thanks! Exactly what I've been looking for. I agree with your thought that as the article says it's adds additional security, your way seems the better option. Will dig into this and try to understand what it really does and how I should do to not screw things up :) Again, Thanks @UnqtiousDude :D Aug 15, 2017 at 7:18

Suppose you're in mysite.com/public and you want the index.php or drupal root should come directly under mysite.com/public then do this:

Then execute:

create-project drupal-composer/drupal-project:8.x-dev my_site_name_dir --stability dev --no-interaction --no-install

now go to my_site_name_dir and move everything including * and .* to under mysite.com

Then open composer.json under mysite.com and then replace "web" occurrences to "public" in installer-paths.

Now run composer install within mysite.com. It will work.

  • Thanks @user5858!! A great way since I didn't manage to use symlink. Will try this ASAP! Thanks again! :D Mar 20, 2019 at 20:52

Everywhere I check the answer to this question of the 'web/' folder is always to reconfigure server and write rewrites, but I have a very simple way I solve this issue.

During initiating a new Drupal project, I would make what is called a 'modified install'. I would stop the project initiation half way to tell Composer what my web-root is. By default Composer assumes my web-root to be 'web/' but making a modified install allows me to tell Composer where it is. If on shared hosting it would be 'public_html' and could be called anything in some other situation. So when I pause the installation process, I would tell Composer, 'hey don't go ahead to install Drupal in 'web', install it 'here' instead' and 'here' could even be a nested folder several steps away from pwd. When I tell Composer this, I then resume the installation process and finally Drupal would be installed wherever I told Composer.

I wrote the steps to do this in a blog post, How to install Drupal 9 with Composer on Cpanel. This post is about installing on a cPanel account but the process demonstrates making a modified install, and same principle can be used to install locally or in any folder structure.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.