I am trying to show a custom 404 not found page in my website with Flutter.
I am using the following code :
MaterialApp(
debugShowCheckedModeBanner: false,
initialRoute: "/",
routes: {
"/": (context) => Scaffold(),
"/test": (context) => TestPage()
},
onUnknownRoute: (settings) {
return MaterialPageRoute(builder: (_) => Scaffold(
body: Center(
child: Text("Page not found !"),
),
));
},
i have rebuild my app and deploy it with Firebase Hosting. However i am seeing this if i enter a wrong url :
Since i am using flutter, i don't really want to add an .html file as it is said, even if it works.
I would rather display a custom page built in dart.
How can i display my custom "Page not found" in such case ?
EDIT :
Here is my current firebase.json file :
{
"hosting": {
"cleanUrls": true,
"public": "build/web",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}
What i have tried and what didn't work :
Not having rewrites
Having rewrites in hope that flutter routing would take the lead
Test the project in localhost
Change the Flutter routing Strategy from URL to PATH according to the documentation
In the end :
My existing pages in the website are working fine
All wrong urls are redirected to /index.html
The only thing that is working is :
Adding a 404.html file in my /build/web folder
Remove rewrites in firebase.json
However this is not what i want, i would like to display my not_found_page.dart instead.
This might be a Flutter issue, i keep this open in the meantime but i will dig deeper on the Flutter side.
The problem was indeed on the Flutter side.
I was using "/" as initialRoute and "/" as another route which was creating conflicts apparently and was actually useless in my code as the first page returned is defined under the MaterialApp's child.
Flutter was redirecting my routes to "/" instead of calling onUnknownRoute and there was a conflict with the rewrites in firebase.json
So i have removed the "/": (context) => Scaffold(), from the routes map.
I have also removed rewrites in firebase.json in order for this to work.
I have also set back the URL strategy, all the steps above were not working with the PATH strategy.
EDIT : i have figured out that the PATH strategy can work only if there is no home property on the MaterialApp widget.
If so, all of the wrong routes will be redirected to the home and not call the onUnknownRoute
For the / route, the home property, if non-null, is used.
Otherwise, the routes table is used, if it has an entry for the route.
Otherwise, onGenerateRoute is called, if provided. It should return a non-null value for any valid route not handled by home and routes.
Finally if all else fails onUnknownRoute is called.
PS : There is no need to implement 404.html file
just add a 404.html page in your root and redirect it your own custom flutter built page.
you can also learn to handle the
'Famous 404 page not found !' from here
Related
I have the following project tree in /public
.
On my website, if I request a non-existent page from a page in /public, e.g. mydomain.com/nonexistentpage, it throws a 404 page properly.
However, if I request a non-existent page from mydomain.com/folder/nonexistentpage, it breaks everything except HTML. Errors thrown in the browser indicate that it's looking for assets in /public/folder/files and /public/folder, while the actual files are in /public/files and /public.
My firebase.json is:
{
"hosting": {
"public": "public",
"cleanUrls": true,
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
}
}
What do I do to make the 404 page appear properly on any page?
Check if you don't use relative paths when using <link>.
I have set up routes on my MaterialApp like this:
routes: {
'/': (context) => const Gate(),
'/ungated': (context) => const LandingPage(gated: false,)
}
it all works fine locally, but when I host it on Firebase hosting and I try to access the /ungated route I get 404 page not found.
also the 404 that I get is not the page I defined in onUnknownRoute: (settings)=> MaterialPageRoute(builder: (_) => _errorRoute(settings))
Any ideas? I feel that I need to change firebase.json but have no idea what to put in there.
EDIT
The problem is because I am using PathUrlStrategy and Firebase Hosting does not work with that. I don't know if it's possible to make it work.
My goal is to have two kinds of dynamic routes on the same path. I want:
mywebsite.com/#username to send people to /pages/[username].tsx
mywebsite.com/page-slug to send people to /pages/[pageSlug].tsx
I tried creating two files:
/pages/[pageSlug].tsx
/pages/[...username].tsx
So that [pageSlug].tsx would have priority, and then everything else would go to [...username].tsx, where I would extract the username from the path and render the page.
It works great locally, but on vercel mywebsite.com/#username pages return 404 error.
I have also tried following this advice about doing this with url rewrites, but it doesn't seem to work.
I have created two files:
/pages/[pageSlug].tsx
/pages/user/[username].tsx
Set up the rewrites in next.config.js:
module.exports = {
reactStrictMode: true,
async rewrites() {
return [
{
source: '/:username(#[a-zA-Z0-9]+)/:id*',
destination: "/user/:username/:id*",
}
]
}
}
And set up the links to the user profiles like so:
<Link href="/user/[username]" as={`#${post.author.username}`}>
{post.author.username}
</Link>
Just loading the http://localhost:3080/#lumen works, but when I click on a link I'm getting:
Error: The provided as value (/#lumen) is incompatible with the href value (/user/[username]). Read more: https://nextjs.org/docs/messages/incompatible-href-as
How can I make this work with the rewrites (or in any other way)? Any advice?
I found in the firebase documents that you could hide the .html extensions of my site by creating a "firebase.json" file. I effectively remove the extensions but when I want to enter my other pages I cannot. I always see the main page.
I tried previously with .htaccess but it didn't work out. Now I found this firebase resource but any extension directs me to the main page.
I put that in my file "firebase.json"
"hosting": {
"cleanUrls": true,
"trailingSlash": false
}
You can set up routes inside of firebase.json. They can either be rewrites (where the url is actually pointing to another location, but that is unknown to the user), or redirects (where the page redirects to another url).
Inside of your firebase.json, hosting should look like this:
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "/sign-up",
"destination": "/sign-up.html"
}
],
"redirects": [
{
"source": "/sign-up.html",
"destination": "/sign-up"
}
]
}
There are 2 added nodes, rewrites and redirects. What this does is whenever someone visits /sign-up, you actually point them to /sign-up.html, where your actual html code is. But when someone visits /sign-up.html on their own, you redirect them to /sign-up.
I am online a fresh webpage for the purpose of universal links. I put the file in .well-known folder.
In the server log I can see that Applebot got 200 on "GET /.well-known/apple-app-site-association HTTP/1.1"
The only error displayed in the App Search API Validation Tool is:
"example.com is returning 469. Please check your url and try again."
I used another tool to check it - branch.io AASA Validator and it displays no errors.
Also make sure you don't have any robots.txt file in the root that disables Applebot
Robots.txt: allow only major SE
https://support.apple.com/en-us/HT204683
Looks like apple changed the format of AASA file. According to this official document, the old presentation
{
"applinks": {
"apps": [],
"details": [
{
"appID": "{PREFIX}.{BUNDLE_ID}",
"paths": ["*"]
}
]
}
}
Had already changed to:
{
"applinks": {
"details": [
{
"appIDs": [
"{PREFIX}.{BUNDLE_ID}"
],
"components": [
{
"/": "/*"
}
]
}
]
}
}
Considering backward compatibility, you can try writing in this format:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "{PREFIX}.{BUNDLE_ID}",
"paths": ["*"],
"appIDs": [
"{PREFIX}.{BUNDLE_ID}"
],
"components": [
{
"/": "/*"
}
]
}
]
}
}
This works for me, hope it helps.
What worked for me was adding image metadata on top of title and description metadata. I also added Touch icons, but I do not think it caused the issue since it works fine on another website I have without it.
Required metadata seems to be: Title, description and Image (og:image was the missing one in my case)
For metadata check out: The Open Graph Protocol
For icons check out: Developer Apple - Configuring Web Applications