'React Router: Ignore Pattern before ID (my-seo-url-string-84345)

I would like to create a SEO friendly URL pattern on clientside. The ID of an article is fetched from the server by searching for the ID.

https://www.myurl.com/854353

I would like to integrate the title of the article in the URL on the clientside, to have more SEO friendly URLs.

https://www.myurl.com/this-is-my-articles-name-854353

That means, only the last part of the URL must be considered to fetch the data correctly from the server. All hyphens before must be ignored.

How can I achieve this using React Router?

The following example with a user's profile.

So bascially the implementation is:

https://myurl.com/vendor/c0la

And I would like to attach a SEO-friendly string. That means, the router only must consider the "small_id", not the string before

https://myurl.com/vendor/firstname-lastname-location-other-stuff-c0la

App.js

    <Routes>
      <Route exact path="/" element={<Home />} />
      <Route exact path="/chats" element={<Chats />} />
      <Route exact path="/profil" element={<Profile />} />
      <Route path="/vendor/:small_id" element={<ViewProfile />} />
      <Route exact path="/dashboard" element={<Dashboard />} />
      <Route exact path="/verwaltung" element={<File />} />
    </Routes>

SearchResults.js (This links to the profile)

<div className="section-box profile" key={key} onClick={() => navigate('/vendor/' + user.small_id)}>

ViewProfile.js (The profile of the found users)

    const { small_id } = useParams(); // Must match the pattern used in the router
    
    React.useEffect(() => {
        axios.get('/api/profiles/get/' + small_id)
            .then(res => {
                if (res.status === 200) {
                    setProfile(res.data);
                }
            })
            .catch(err => {
                //toast.error("Der Benutzer wurde nicht gefunden", { theme: 'colored' });
            })
    }, []);


Solution 1:[1]

So I would change your route to the following:

  <Routes>
      <Route exact path="/" element={<Home />} />
      <Route exact path="/chats" element={<Chats />} />
      <Route exact path="/profil" element={<Profile />} />
      <Route path="/vendor/:firstname-:lastname-:location-:moredata-:small_id" element={<ViewProfile />} />
      <Route exact path="/dashboard" element={<Dashboard />} />
      <Route exact path="/verwaltung" element={<File />} />
    </Routes>

I would then re build your link to include those:

<div className="section-box profile" key={key} onClick={() => navigate('/vendor/' + user.firstname + '-' + user.lastname + '-' + user.location + '-' + user.moredata + '-' + user.small_id)}>

The below should still work:

 const { small_id } = useParams(); // Must match the pattern used in the router
    
    React.useEffect(() => {
        axios.get('/api/profiles/get/' + small_id)
            .then(res => {
                if (res.status === 200) {
                    setProfile(res.data);
                }
            })
            .catch(err => {
                //toast.error("Der Benutzer wurde nicht gefunden", { theme: 'colored' });
            })
    }, []);

** Please note I have not tested this!

Solution 2:[2]

I did some research and discovered that React Router V6 does not accept optional parameters anymore. So I came up with the following solution:

<Route path="/vendor/:seo+:small_id" element={<ViewProfile />} />

That means the path can look like: https://mywebsite.com/vendor/+843242

And ":seo" is basically optional. You do not need this, if you implement the server routing like this:

const { small_id } = useParams(); // Must match the pattern used in the router

    React.useEffect(() => {
        axios.get('/api/profiles/get/' + small_id)
            .then(res => {
                if (res.status === 200) {
                    setProfile(res.data);
                }
            })
            .catch(err => {
                toast.error("Der Benutzer wurde nicht gefunden", { theme: 'colored' });
            })
    }, []);

So everything before :+small_id can be fully customized for SEO purposes. You can route what you want clientside.

<div className="section-box profile" key={key} onClick={() => navigate('/vendor/' + user.firstname + "-" + user.lastname + "-" + user.workplaces + "+" + user.small_id)}>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Abdush Samad Miah
Solution 2 Troublegum