Use public folder as Domain Root
It is important that the domain address does not point to the root project directory. Follow my instructions to make the domain point to the /public folder from the beginning, so you don't have to apply .htaccess redirection and your website will be much more secure.
More information about "How to config domain to Laravel app?" - StackOverflow Answer
The /public appears in the URL if your domain name points to your-project instead of your-project/public. Therefore, you can access your starting index.php with https://example.com/public/index.php.
# normal directory tree
server
├── your-project
│ ├── app
│ ├── routes
│ ├── public <--- domain root
│ │ ├── index.php
│ │ └── .htaccess
│ ├── ...
If the root of your domain points to the /your-project/public folder and you can still access its content using the /public address, then either you have incorrectly set up the Route in the /routes/web.php file (perhaps created a group named "public" or added the /public URL part to every route), or your domain is pointing to the /your-project folder incorrectly.
Set .htaccess
# normal directory tree
server
├── your-project
│ ├── app
│ ├── routes
│ ├── public <--- domain root
│ │ ├── index.php
│ │ └── .htaccess <--- must be inside the domain root folder
│ ├── ...
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
.htaccess from laravel/laravel starter application
Set storage to public
If the domain address already points to the /public folder, then from there you can access the /storage/app/public folder using a symbolic link. The symbolic link should be placed in the /public folder with the name "storage".
This way, when you access the /public/storage folder, you are actually entering the /storage/app/public folder. Since the domain address points to the /public folder, the storage folder becomes immediately accessible via the symbolic link with the URL http://example.com/storage.
How to can generate /public/storage symbolic link?
# will run from project root folder
php artisan storage:link
More information about storage folder on Laravel Framework - StackOverflow Answer
A virtual reference that associates a non-existent path with an existing one. In our example, we can associate the non-existent path public/storage with the physically existing storage/app/public directory.
How? We have two options for this. Either use the php artisan storage:link command in Laravel specifically designed for this purpose, or manually set it up in the operating system.
Obviously, the former is the more obvious solution.
# normal directory tree
server
├── your-project
│ ├── app
│ ├── routes
│ ├── public
│ │ ├── storage <--- symbolic link (to /server/your-project/storage/app/public)
│ │ ├── index.php
│ │ └── .htaccess
│ ├── storage
│ │ ├── app
│ │ │ └── public <--- here can store your files (really folder)
│ │ ├── framework
│ │ └── logs
│ ├── ...
If you create the symbolic link, it will work as expected. For example, you can access the storage/app/public/images/test.png file through a virtual path: public/storage/images/test.png.
More information about symbolic links - StackOverflow Answer