Refresh page on apache with React doesn't work - .htaccess

I'm trying to use React to create a SPA, but I'm running into problem when trying to reload the page.
Before I continue, I must say I already read these questions this and this. I manageg to made it work, but only for the first url.
For example, I have a blog page containing all the posts, accessed via this url mysite.com/blog. This one works fine, if I refresh the page, everything reloads again.
However, when I try to access a single post using a dynamic url, then the page doesn't work. For example, I have this router setup:
// Definiton
<Route path="/post/:url" component={Post} />
// Link
<NavLink to={"post/" + post.url}>...</NavLink>
// Url on the browser
mysite.com/post/this-is-my-first-post
In this case, it's not working. This is my .htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
After looking more at the problem, I noticed it's trying to load the main files from a different location. For example, when I'm on the page mysite.com/blog it's loading the .css and .js files from mysite.com.
But when I'm the page mysite.com/post/this-is-my-first-post and I refresh the page, it's trying to load the .css and .js files from the directory mysite.com/blog.
I did what Stuffix told in the answe, to check the url definition and also the config at my apache, but everything is enabled and working, just like the answer says.

Well, after looking at some other projects I have using Angular, I noticed one thing, and it was easier than I tought.
Just had to add the tag base on the head of my index.html.
<base href="/" />

This htaccess worked for me with react and angular
<IfModule mod_rewrite.c>
RewriteEngine on
# -- REDIRECTION to https (optional):
# If you need this, uncomment the next two commands
# RewriteCond %{HTTPS} !on
# RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
# --
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^(.*) index.html [NC,L]
</IfModule>

In your <Route />, you're declaring the post route is /post/this-is-my-first-post which is correct.
But in your <NavLink />, you're pointing towards /blog/post/this-is-my-first-post since you've missed a slash.
<NavLink to={"post/" + post.url}>...</NavLink>
| here
Thus leading to a 404.
If this doesn't help, your snippet looks fine so the problem might be on what does post.url returns.
Also, your .htaccess looks fine so I would say you might have missed something in your Apache config like AllowOverride all. See this answer.

Related

htaccess rewrite to a page that can or cannot have ids

I'm trying to create a htaccess rule to rewrite the following URL's:
localhost/abc/def/1 (or with trailing slash would be fine)
to
localhost/abc/def.php?id=1
accessing just
localhost/abc/def/ is also valid, and it's working.
My code so far:
RewriteEngine On
Options +FollowSymLinks
Options All -Indexes
RewriteEngine On
RewriteCond %{REQUEST_URI} !(\.css|\.js|\.png|\.jpg|\.jpeg|robots\.txt)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^index$ ./src/index.php [NC,L] # it works
RewriteRule ^def/?$ ./src/def.php [NC,L] #works too!
RewriteRule ^def/(.*)?$ ./src/def.php?id=$1 [NC,L] #this doesnt
I've read some posts like this one Rewrite Rule To Detect Numbers Only but they didn't work for me.
The weird thing is, if i change the slash between def and the id part with underline, it does work, like this:
RewriteRule ^def_(.*)?$ ./src/def.php?id=$1 [NC,L]
But the URL becomes localhost/abc/def_1 and doesnt look that good.
UPDATE:
Site structure:
/home/username/public_html/abc/ (have multiple websites on public_html)
|_media/
|____js/
|____css/
|____images/
|_src/
|____def.php
|____fgh.php
|_.htaccess
When the rule to redirect def/1 does work, the media url's within the page are also being translated to:
http://localhost/abc/def/css/bootstrap.min.css
Thanks!
Reproducing your case scenario, I've made the follow folder structure:
/home/username/public_html/
|_ abc/
|___ .htaccess
|___ src/
|_____ def.php
In my .htaccess located inside the abc folder, I have the following:
RewriteEngine On
RewriteRule ^def/?$ src/def.php [NC,L]
RewriteRule ^def/([1-9]+)/?$ src/def.php?id=$1 [NC,L]
And all the scenarios you mentioned work as expected.
These 2 go to def.php:
domain.com/abc/def
domain.com/abc/def/
These 2 go to def.php?id=1 and def.php?id=3 respectively:
domain.com/abc/def/1
domain.com/abc/def/3/
I am afraid you might have additional .htaccess or rules taking effect or even your browser cached not giving the proper information you want.
Try using a different browser and try the above exactly as I described it.

htaccess | not looking in the right location for js

I am trying to write a htaccess file that will allow for /example/1/profile to look for a JavaScript file within /example/. Currently on Internet Explorer 11 it is looking for /example/1/file.js whereas realistically it should be looking for /example/file.js.
This needs to be done inside of the .htaccess file as the setup that the website currently has.
I know there is a way in which you can redirect 404 to /example however this is resulting in a 200.
Is their a way I can say in the htaccess file that if it is .js .css to look in /example?
Thanks in advance
EDIT:
For a little but more information, my current htaccess is like this
DirectoryIndex index.php index.html
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^(.*) /example/index.php [NC,L]
It is for php because the php echos a file_get_contents of the index.html which is an Angular project.
So I need this htaccess to be the following logic
If the file is a .js or .css then rewrite the location to /example else rewrite the location to example/index.php.
The reason this is happening is because I am doing a format which has the ID as a second parameter and for some reason this is interfering with the way that the URL is structured for the js, css.
I imagine this line is what is breaking it...
RewriteRule ^(.*) /example/index.php [NC,L]
Converting my comments to answer. This appears to be problem due to relative links.
To fix, you can add this just below <head> section of your page's HTML:
<base href="/example/" />
so that every relative URL is resolved from that base URL and not from the current page's URL.

Codeigniter sub-folder multiple controllers

Here is my htaccess file and it works somewhat. Not matter what controller I specify it always goes to the home page
<IfModule mod_rewrite.c>
RewriteEngine On
#Checks to see if the user is attempting to access a valid file,
#such as an image or css document, if this isn't true it sends the
#request to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#This last condition enables access to the images and css folders, and the robots.txt file
RewriteCond $1 !^(index\.php|css|js)
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>
This is my website URL
http://automationmetrics.local/automation/
Thoughts?
Some things I usually check when this happens to me:
Have I enabled the mod_rewrite module in Apache?
Have I set $config['index_page'] to blank?
If the above works, here's the one that I use, that's working on my end:
https://gist.github.com/petrepatrasc/6925413
If you're STILL out of luck, then try fiddling with the $config['uri_protocol'] parameter - I remember that I could only get it to work on Windows (with IIS at the time) using REQUEST_URI as a value. Might be related to that.
The first two rules get triggered on all the files, just like it says in the comment. So this one:
RewriteCond $1 !^(index\.php|css|js)
seems redundant and removing it should solve the issue you're having.

Htaccess rule to make urls like this ?page=1 look like /page/1 in Codeigniter

This is how my urls currently look:
http://mysite.com/?page=1
How can I make this work?:
http://mysite.com/page/1
There is a post on StackOverflow that asks the same question. But the accepted solution isn't working for me. Because I am using Codeigniter and my page results in a 404 perhaps because since the url pattern of a CI site is:
domain/controller/method
The system is assuming that I am requesting a controller called "page" and a method called "1" both of which of course doesn't exist. Or maybye it's due to a conflict with the other code in my htaccess file (which I downloaded from the CI wiki, it gets rid of index.php and does a few security things). Here is my entire htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
#Removes access to the system folder by users. Additionally this will allow you to create a System.php controller, 'system' can be replaced if you have renamed your system folder.
RewriteCond %{REQUEST_URI} ^system.*
RewriteRule ^(.*)$ /index.php?/$1 [L]
#When your application folder isn't in the system folder. This snippet prevents user access to the application folder. Rename 'application' to your applications folder name.
RewriteCond %{REQUEST_URI} ^application.*
RewriteRule ^(.*)$ /index.php?/$1 [L]
#Checks to see if the user is attempting to access a valid file, such as an image or css document, if this isn't true it sends the request to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
#Pretty urls for pagination links
RewriteRule (.*) index.php?page=$1
</IfModule>
The non indented bit is the solution I got from that other SO question that isn't working for me.
Any solutions to this CI pagination issue?
UPDATE
Ok, read some of the docs and now I have this working:
http://mysite.com/home/index/2
What would be the htaccess rule to turn that into?:
http://mysite.com/page/2
You should make this configuration at /application/config/routes.php (and let the .htaccess just for hide the index.php as you are already doing).
$route['page/(:any)'] = 'home/index/$1';
Or better, like #zaherg remembered (ensures that only numbers could by matched):
$route['page/(:num)'] = 'home/index/$1';
This way all the requests to http://mysite.com/page/2 will be treated internally as http://mysite.com/home/index/2 and so forth.
I suggest you take a look at CodeIgniter User Guide - URI Routing and CodeIgniter User Guide - Tutorial − Introduction.
Good luck.
RewriteEngine on
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
from CodeIgniter docs
That will handle removing the index.php, but what happens after that depends how CodeIgniter's query string handling is set up: it can be configured to use a query string rather than a path. See the link for more details.

ignore specific directories in htaccess using mod_rewrite

I've got the following code in my .htaccess to strip out index.php from the urls in my CMS-based site.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
This code works great and it routes requests exactly how I want. For example, with URL: http://example.com/contact/ the directory contact doesn't actually exist if you look in the FTP; instead index.php handles the request and shows my contact info. Perfect. Well, almost perfect.
I want to modify this code to specify a couple directories in FTP that should be ignored. For example, if I've got a folder called assets, when I go to http://example.com/assets/ the default DirectoryIndex page is displayed. Instead, I want this directory to be ignored -- I want index.php to handle /assets/.
TL;DR: How can I modify the above code to explicitly ignore certain existing directories (so that index.php handles them instead of the DirectoryIndex)?
Why not adding this below or before your code?
RewriteRule ^(assets/.*)$ /index.php/$1 [L]

Resources