Search code examples
reactjsnext.jsserver-side-rendering

Fetch data using an id from an api but display an alternative text to address bar e.g. content_title in Next.js


I'm using an api that only allows fetching data using an id BUT NOT title as follows http://0.0.0.0:5000/blog/13b03a39-bc04-4604-baf6-059658f9f5e8 . The endpoint returns a JSON object which I want to render to browser using Next Js. However I want to have a clean url architecture that contains title as follows:

clean

instead of a url containing the id as follows:

dirty

Here's how I'm passing props to Link :

<Link
    href={`/post/${post.blog_title}`}
    as={`/post/${post.blog_title}`}>
    
    <a className='blog__card--link'>
        <h4 className='blog__card--title'>{post.blog_title}</h4>
    </a>
</Link>

and here's is my [id].js file:

import { getBlog } from '../../api/index';

const Article = ({ blog }) => {
    const router = useRouter();

    return (
        <div class='article'>
            <div class='article__main'>
                {/* {console.log(router)} */}
                <ArticleView />
            </div>
        </div>
    );
};

Article.getInitialProps = async (router) => {
    const res = await getBlog(`${router.query.id}`);
    const json = await res.json();
    console.log(json);

    return { blog: json };
};

export default Article;

Trying to access ${router.query.id} in getInitialProps it returns the title which I understand is what I'm passing through as prop in Link.

Is it possible to achieve a clean url structure but also use id in getInitialProps? and how can I achieve it using dynamic links in Next.js ?

IMPORTANT UPDATE

-> The only good alternative is to use slugs in the API because imagine someone follows a link to your post from another site or perhaps enter the URL in the browser address bar? How would you know what to query for from the backend? Therefore this question comes from a place of impracticality , choosing to retain it on the site for the sake of others in the future.


Solution

  • solution 1 however this base on your endpoint my suggest is change endpoint to receive slug so you can manage your slug

    solution 2 not best practice but you can get clean url and get data by id Using Redux

    solution 3 using next-routes using next-routes and pass id as params

    <Link route='blog' params={{id: data.id}}>
    <a>Hello world</a>
    </Link>