[7.2-7.3] Plugin development routes best practices

Hi there!

I'm developing (trying to, actually) a Kibana plugin (already opened couple of threads about it).

Here I wanted to ask you which was the best way to implement routing across the plugin pages.

Let's say in the main page of the plugin I start selecting the index pattern as a link (similar to what happens when selecting the index pattern in the machine learning plugin).

Clicking on the desired index-pattern, I'd like to go on to the next page (let's say to /category page), obviously keeping the info about the selected index pattern stored in props.
Which is the best way to accomplish that? Do I simply use Router and Route in the Main component or do I have to set something in the server/ folder?

Thank you

Hey @Fabio-sama! Client-side routing is done a number of ways within Kibana, there isn't really one right way at this point in time. You don't have to put anything in the server/ folder to accomplish this. Internally, a lot of applications use React Router. I'd highly recommend staying away from AngularJS's routing. I'd recommend looking at some internal usages of react-router-dom for inspiration and precedent.

Thank you for the reply.

I'm trying with React Router but I'm having some problems.
Following the video you linked I imported

import { BrowserRouter as Router, Route, Link } from 'react-router-dom'

Then I wanted to render a EuiInMemoryTable listing all the index-patterns and I wanted to go to the next page of the plugin at the URL #/{index-pattern} (without really seeing the hash # but the url I am at the moment, so localhost:5603/uif/app/my_plugin/my-index-pattern)

So I did something like:

return (
  <Router>
    <React.Fragment>
      <EuiInMemoryTable
        items={this.state.items}
        loading={this.state.isLoading}
        columns={[
          {
            field: 'label',
            name: this.props.table_title,
            render: (index) => (
              <span>
                <EuiIcon
                  type={this.props.icon_type}
                  size="m"
                  style={{ verticalAlign: 'text-top' }}
                />{' '}
                <EuiLink href={`/uif/app/my_plugin/${index}`} target="_self"> {/* <<<<< HOW CAN I AVOID TO WRITE THE WHOLE URL AND NOT SEE THE # EITHER ? */}
                  {index}
                </EuiLink>
              </span>
            ),
            sortable: true,
            truncateText: true,
          }
        ]}
        search={search}
        pagination={true}
        sorting={true}
      />
      <Route path='/uif/app/my_plugin/:index' component={Test}/>
    </React.Fragment>
  </Router>
);

And below I defined the component

const Test = () => (
  <div>
    <h1>Test</h1>
  </div>
)

When I click on one of the links in the table on the landing (first) page, I would expect to be redirected to a blank page with only a write Test in it.
Instead I get
image
Even though the URL is the one I would expect (http://localhost:5603/uif/app/my_plugin/kibana_sample_data_flights)

It means I'm not correctly redirecting it to the component I want to show. How can I do that?

Thanks!

I even tried using the switch (obviously importing it) like

return (
  <Router>
    <React.Fragment>
      <EuiInMemoryTable
        items={this.state.items}
        loading={this.state.isLoading}
        columns={[
          {
            field: 'label',
            name: this.props.table_title,
            render: (index) => (
              <span>
                <EuiIcon
                  type={this.props.icon_type}
                  size="m"
                  style={{ verticalAlign: 'text-top' }}
                />{' '}
                <Link to={`/uif/app/my_plugin/${index}`} target="_self">
                  {index}
                </Link>
              </span>
            ),
            sortable: true,
            truncateText: true,
          }
        ]}
        search={search}
        pagination={true}
        sorting={true}
      />
      <Switch>
        <Route path="/uif/app/my_plugin/kibana_sample_data_flights">
          <Test />
        </Route>
      </Switch>
    </React.Fragment>
  </Router>
);

And here I tried defining the functional component Test.js and importing it, rather than using const below the code.

Same 404 error.

Sorry to bother you, but can't you help me further?

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.