Relocated web root on shared hosting

Last updated on
24 January 2026

The recommended method of running a Drupal site is with a "relocated document root" in /web:

[...] the files "index.php" and the "core" directory and so on are placed inside a subfolder named "web" rather than being placed next to "composer.json" and the "vendor" directory at the project root.

From Starting a site using Drupal Composer project templates.

Getting Drupal served from /web can be a challenge on shared hosting, where you have limited options, and cannot edit Apache config files. Here are a few methods.

Set DocumentRoot via settings

If your control panel exposes the DocumentRoot option, that’s the cleanest fix.

  1. cPanel: In the domain / addon-domain settings you can set the Document Root. Set it to /home/username/public_html/web (or whatever the absolute path is).
  2. Plesk: In Hosting Settings for the domain change Document root to the web subfolder (e.g. httpdocs/web).
  3. Hetzner: Set document root to /[projectname]/web in konsoleH.

If you cannot set document root via GUI, see "Use subdomain to set DocumentRoot" below.

Redirect with .htaccess file

You can redirect requests internally with a .htaccess file.

  1.  Add this in public_html/.htaccess (you have to create this file):
    RewriteEngine on
    RewriteRule (.*) web/$1 [L]
  2. In /web/.htaccess:
    No changes
  3. Add this in settings.php:
    if (isset($GLOBALS['request']) && '/web/index.php' === $GLOBALS['request']->server->get('SCRIPT_NAME')) {
      $GLOBALS['request']->server->set('SCRIPT_NAME', '/index.php');
    }
    elseif (isset($GLOBALS['request']) && '/web/update.php' === $GLOBALS['request']->server->get('SCRIPT_NAME')) {
      $GLOBALS['request']->server->set('SCRIPT_NAME', '/update.php');
    }

Originally from #2612160: Redirects being built as http://localhost:8888/drupal8 and not considered safe by RedirectResponseSubscriber, see also for more options.

Use subdomain to set DocumentRoot

You may not be able to set the DocumentRoot for your main domain, i.e. example.org via settings. One method is to create a subdomain like www2.example.org, where you can point the DocumentRoot to the /web folder.

From your main domain's public_html folder, you can redirect to the www2 subdomain via a small index.html file, with <meta http-equiv="refresh" content="0; url=www2.example.org" />.

This makes your site available through your subdomain www2.example.org rather than main domain example.org. It seems like you cannot create the subdomain www, at least for cPanel.

Warning: Only use this method if you are an experienced Unix user.

You should probably try the "Redirect with .htaccess file" method first, since it's less complicated.

If you have SSH access and permissions to create a symlink, you can place the Drupal files in a folder outside the public_html folder, and instead serve the /web-folder via public_html using a symlink.

  • Assuming this is your home folder: /home/[username]
  • Assuming this is the public_html folder: /home/[username]/public_html
  1. Place your Drupal folder here:
    /home/[username]/drupal10
  2. Rename the public_html folder (or delete it, if you can):
    mv public_html public_html_OLD
  3. Create a symlink from public_html to web:
    ln -s /home/[username]/drupal10/web /home/[username]/public_html

Now, the files from /web will be served via the symlinked public_html-folder. Run Composer and Drush commands from the drupal10 folder, not public_html.

Additional examples and info

See How do I set up a Composer install of Drupal to run from domain root not the web sub-folder.

Help improve this page

Page status: No known problems

You can: