Skip to content
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

[docs] High-level Routing, Navigation and URL overview #76888

Merged
merged 16 commits into from
Sep 15, 2020

Conversation

Dosant
Copy link
Contributor

@Dosant Dosant commented Sep 7, 2020

Summary

Closes #76288

This pr adds a page that gives a high-level overview of available tools and explains common approaches for handling routing, browser navigation and URL in Kibana.

Such guide is something we were asked for in one of the latest surveys

@Dosant Dosant added docs Feature:New Platform Feature:StateManagement release_note:skip Skip the PR/issue when compiling release notes Team:AppArch Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v7.10.0 v8.0.0 labels Sep 7, 2020
@Dosant Dosant changed the title overview around navigation [docs] Routing, Navigation and URL guide Sep 7, 2020
@Dosant Dosant changed the title [docs] Routing, Navigation and URL guide [docs] High-level Routing, Navigation and URL overview Sep 7, 2020
@Dosant Dosant marked this pull request as ready for review September 7, 2020 17:26
@Dosant Dosant requested a review from a team as a code owner September 7, 2020 17:26
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-app-arch (Team:AppArch)

@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-platform (Team:Platform)

@Dosant Dosant requested review from stacey-gammon and a team September 7, 2020 17:26
Copy link
Contributor

@pgayvallet pgayvallet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this is a great addition to the documentation.

Some comments, mostly on the fact that the basePath handling seems to have been forgotten in the examples.

docs/developer/best-practices/navigation.asciidoc Outdated Show resolved Hide resolved
docs/developer/best-practices/navigation.asciidoc Outdated Show resolved Hide resolved
docs/developer/best-practices/navigation.asciidoc Outdated Show resolved Hide resolved
docs/developer/best-practices/navigation.asciidoc Outdated Show resolved Hide resolved
docs/developer/best-practices/navigation.asciidoc Outdated Show resolved Hide resolved
@Dosant
Copy link
Contributor Author

Dosant commented Sep 8, 2020

Thanks @pgayvallet, I made edits with your suggestions 👍

Copy link
Contributor

@pgayvallet pgayvallet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the changes. LGTM

Copy link
Contributor

@streamich streamich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

docs/developer/best-practices/navigation.asciidoc Outdated Show resolved Hide resolved

[source,js]
----
window.location.href = core.http.basePath.prepend(`/dashboard/my-dashboard`); // (try to avoid this)
Copy link
Contributor

@streamich streamich Sep 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason this code block has almost no syntax highlighting:

image

I wonder if it is how our website is set up or does it has to do with [source,js].

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great example, but I was initially confused because you say "using native browser apis" but part of the example is using core apis.

What if we had the "Deep linking into Kibana Apps" section first, so the user is introduced to the core api core.http.basePath.prepend and what it does and that it should only be used if there isn't a url generator available?

Then you can follow up with this section and I think the user may understand that you are focusing on the window.location.href part of the line.

Could then even write it as:

const discoverUrl = discoverUrlGenerator.createUrl({filters, timeRange});
// Avoid this, as it will cause a full page reload.
window.location.href = discoverUrl;

Which focuses in on which is the part to avoid.

docs/developer/best-practices/navigation.asciidoc Outdated Show resolved Hide resolved
docs/developer/best-practices/navigation.asciidoc Outdated Show resolved Hide resolved
docs/developer/best-practices/navigation.asciidoc Outdated Show resolved Hide resolved
----


As it would be too much boilerplate to do this for each {kib} link in your app, there is a handy HOC that helps with it:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should not mention RedirectAppLinks in this doc as it is a hack to easily make legacy Kibana URLs work. Or mention that it is a hack and you should not be using it.

It seems we are missing a good way to navigate across Kibana apps, we need a component where one specifies an app and path:

<KbnLink app={'discover'} to={'/foo/bar'}>
  Click me!
</KbnLink>

Copy link
Contributor

@streamich streamich Sep 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe in kibana_react we could put a component that can do both, navigate within Kibana app:

import { Link } from 'src/plugins/kibana_react/public';

<Link to={'/foo/bar'} />

and across apps if app prop is specified:

<Link app={'discover'} to={'/foo/bar'} />

Copy link
Contributor Author

@Dosant Dosant Sep 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that component would makes sense.

RedirectAppLinks still worth a mention. Some places don't have React wired up and you need to make sure your non React links are nested into that component.

Copy link
Contributor

@pgayvallet pgayvallet Sep 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should not mention RedirectAppLinks in this doc as it is a hack to easily make legacy Kibana URLs work. Or mention that it is a hack and you should not be using it.

Late reply, but RedirectAppLinks is, AFAIK, not a hack, and the current preferred approach. See #58751 for more context and the whole discussion about the various options. The issue is still open for proposals for possible alternative to match other uses cases (the KbnLink was one of them, so I'm totally in favor of adding that though, see #58751 (comment))

docs/developer/best-practices/navigation.asciidoc Outdated Show resolved Hide resolved
docs/developer/best-practices/navigation.asciidoc Outdated Show resolved Hide resolved
docs/developer/best-practices/navigation.asciidoc Outdated Show resolved Hide resolved
docs/developer/best-practices/navigation.asciidoc Outdated Show resolved Hide resolved
Copy link
Contributor

@stacey-gammon stacey-gammon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So much ❤️ for these doc additions!! Thanks @Dosant!

Few nitpicky comments, but overall, LGTM!

docs/developer/best-practices/navigation.asciidoc Outdated Show resolved Hide resolved
docs/developer/best-practices/navigation.asciidoc Outdated Show resolved Hide resolved

[source,js]
----
window.location.href = core.http.basePath.prepend(`/dashboard/my-dashboard`); // (try to avoid this)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great example, but I was initially confused because you say "using native browser apis" but part of the example is using core apis.

What if we had the "Deep linking into Kibana Apps" section first, so the user is introduced to the core api core.http.basePath.prepend and what it does and that it should only be used if there isn't a url generator available?

Then you can follow up with this section and I think the user may understand that you are focusing on the window.location.href part of the line.

Could then even write it as:

const discoverUrl = discoverUrlGenerator.createUrl({filters, timeRange});
// Avoid this, as it will cause a full page reload.
window.location.href = discoverUrl;

Which focuses in on which is the part to avoid.

**When you should consider using state syncing utils:**

* You want to sync your application state with URL in similar manner Analyze group applications do.
* You want to follow platform's <<history-and-location, working with browser history and location best practices>> out of the box.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So seems like I can use ScopedHistory without using any state syncing utils directly?

Exactly!

ScopedHistory is a core's wrapper around browser's navigation and history apis.

  1. Whenever you want to use window.location or window.history, you should consider using core's ScopeHistory instead. (for example, reading / writing query params, updating path, etc..)
  2. You can use it for listening to location changes. You can't do it with native apis. (Native api's are limited and support only popState or hashChange)
  3. You should initialize your app's react router with it.
  4. And you should initialize state state syncing utils with it! So inside state syncing utils are using core's history instance, instead of browser's api's directly


- You want to sync your application state with URL in similar manner analyze applications do that.
- You want to follow platform's <<history-and-location, working with browser history and location best practices>> out of the box.
- You want to support `state:storeInSessionStore` escape hatch for URL overflowing out of the box.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So state:storeInSessionStore relies on _a and _g parameters in the URL?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, not really.

When using state syncing utils (with kbnUrlStateStorage to be precise) you can configure your state to be synced to any query key. You can also set it up to sync only hash into URL. This is covered in docs of stateSync, which is linked from this general guide: https://github.com/elastic/kibana/blob/master/src/plugins/kibana_utils/docs/state_sync/storages/kbn_url_storage.md#setting-url-format-option

Copy link
Contributor

@cjcenizal cjcenizal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much for writing this up! I read through the preview, but wasn't as thorough as I could have been. I did find one formatting error.

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Build metrics

distributable file count

id value diff baseline
default 45548 +1 45547
oss 27225 +1 27224
total +2

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Feature:New Platform Feature:StateManagement release_note:skip Skip the PR/issue when compiling release notes Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v7.10.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Docs] High level overview on URL recommendations and how state containers plays a role
7 participants