-
Notifications
You must be signed in to change notification settings - Fork 27.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clarify the rules/requirements around the base href
tag in web index.html
#154620
Comments
I added a relative base href of relative_base_href.mp4I don't know if this necessarily means there are no bugs for any kinds of routing, but on the surface it seems to me that relative base hrefs are working fine. They solve an issue for DevTools with some web IDEs that proxy by rewriting paths (flutter/devtools#8067) but I'm a little nervous about going ahead with this without some further confirmation that this is ok. |
Does the app use
|
It uses
It's not clear to me why this is, and that's what this issue is about. It appears to be working correctly, and it's not clear to me why (if it did need to be absolute), Flutter can't just resolve it in the same way that the browser does. Flutter isn't involved in the loading of the So, I guess the request is initially for an explanation of why this can't work and/or where it doesn't work, so I can reproduce (and perhaps contribute a fix for) the issue. |
And just to be clear, I am talking about the base href being computed correctly by the server here. If the backend is serving up the contents of |
I'm afraid your example may seem to be working because the app routes are only one level deep (i.e.
Please keep an eye on the network tab in the above cases and keep note of the URLs that the files are loaded from. If my understanding is correct (BIG IF), then you'll see files loaded from |
Those URLs don't work for DevTools, because its routing is not set up for them. I'll try to make a smaller sample I can test these things with - though if you know of any existing sample app that is already set up with routing like this that I would test with, please let me know! |
In order to repro the cases I mentioned, you can try the following sample: import 'package:flutter/material.dart';
import 'package:flutter_web_plugins/url_strategy.dart';
void main() {
usePathUrlStrategy();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp();
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
initialRoute: '/home',
routes: {
// This is fine with a relative base href.
'/home': (_) => HomePage(destination: '/profile/'),
// This isn't fine because it has a trailing slash, adding one level of
// nesting in the path.
'/profile/': (_) => HomePage(destination: '/deep/path'),
// This is also not fine because it adds nesting in the path.
'/deep/path': (_) => HomePage(destination: '/home'),
},
);
}
}
class HomePage extends StatelessWidget {
const HomePage({required this.destination});
final String destination;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: TextButton(
onPressed: () {
Navigator.of(context).pushNamed(destination);
},
child: Text('Next: `$destination`'),
),
),
);
}
} You will also need to apply this patch in flutter/flutter to loosen the base href requirements in order to test this: #155320 Steps:
The above doesn't have the |
@mdebbar thank you for the sample - although I'm unable to reproduce any issue with it. I pushed a copy of it here: https://github.com/DanTup/repros_flutter_154620 I extracted the routes to I added a small web server script that serves the app up at Even without your patch to Flutter, I can navigate the app fine, both if loaded at the default URL, and also if I hard-refresh so that the initial page is loaded from one of the nested routes. relative.base.href.mp4I can't think of any cases this repro doesn't cover - do you know if I've overlooked something? |
This tells me you are using an absolute path as your base href. I can't confirm since you didn't include If you try a relative base href in your My point is:
|
You just need to run the command in the readme ( |
I'm rewriting the base href to relative in the web server. I don't think some of the code in your PR actually runs for this case, but what I'm trying to determine/clarify is whether this is allowed. There are places in Flutter that say it's not allowed, but it's not clear if they only apply to things like the template (which is modified during the build step), or whether they intended to also cover just runtime where the index.html file is being generated by something that knows how to handle it. So I'm not asking about what can go in |
Oh my bad, I misunderstood what you were doing. I get it now. You are setting the base href on the fly when you serve
Server:Relative base href is NOT supported with If you use your own server instead of Client:Our client side code should work just like any other web app when it comes to base href. We use it in On the client, relative vs absolute base href doesn't make a difference to us because the browser converts it to a full URL (try |
Yes, that's it! Sorry for any confusion 🙂
Understood - this doesn't affect us here -
Great, this is what I hoped (and seemed to be the case in my testing), but the comments about it not being supported in some places made me worry whether this was a policy and could be applied to client/runtime code in future. Is it possible we could make this explicitly clear somewhere (perhaps the text at the bottom of https://docs.flutter.dev/ui/navigation/url-strategies#hosting-a-flutter-app-at-a-non-root-location) to indicate that relative base hrefs work in client apps but the servers must provide them correctly, taking into account the URL a page was loaded at? (I'm happy to open a PR for this and we can agree on the specific wording)? Thanks for your help (and patience)! |
Yes, we should!
That would be amazing! Thank you! |
…untime if appropriately formed There are some places where a relative `base href` is not supported (and these are documented/validated), but there is nothing explicitly calling out that they are supported in the client app. This adds a note to solidify this so they can be used (for example in the DevTools server) without the worry of them being undocumented. Fixes flutter/flutter#154620
I was trying to fix an issue that occurs when using DevTools through a proxy that runs multiple backend hosts through a single hostname, using paths to separate them. For example the address http://localhost:1234/ becomes http://localhost:8888/proxy/1234.
Since the proxy rewrites the request for
/proxy/1234
back to/
, the backend web server does not know that the path (according to the users browser) is/proxy/1234
and therefore cannot provide a correct absolutebase href
. However, providing a relative base href of.
would be correct (or if the request was for a nested route, something like../
).In my testing, this is working fine in DevTools, however the relative base href is always "." (because the DevTools pages are aways at the root right now) so I don't know whether it works generally.
However, there is code and comments in this repo suggesting Flutter requires the base href to always begin and end with a slash:
flutter/packages/flutter_tools/lib/src/commands/build_web.dart
Line 195 in 80e7e4e
flutter/packages/flutter_tools/templates/app_shared/web/index.html.tmpl
Line 8 in 80e7e4e
However I can't find info about why this is required (or more importantly, if it is, whether it could be fixed). On the surface, it feels like an unnecessary limitation (at least for the actual base href - I can understand the argument to
build
being more strict if it wants to avoid mishaps).Is it possible to clarify these rules somewhere (and confirm whether it really is necessary)?
The text was updated successfully, but these errors were encountered: