How to programmatically close bootstrap 5 offcanvas in Next Js - reactjs

I use using bootstrap 5 in my NextJs app my installing like this:
npm install bootstrap and imported the necessary files into my project via _app.js like this:
import 'bootstrap/dist/css/bootstrap.css'
...
useEffect(() => {
import("bootstrap/dist/js/bootstrap");
}, []);
Now the problem is that when I open the offcanvas modal and click a link from there, the offcanvas stays open after the page changes, instead of closing. How do I programmatically close the offcanvas when the pathname changes and only when the offcanvas is active. Thank you
NB: I am not using react-bootstrap

Import like this:-
useEffect(() => {
import("bootstrap/dist/js/bootstrap.bundle");
}, []);

Recently I ran into the same problem, but here is how I got things working.
First of I do not think you are importing bootstrap in to your nextjs app the right way, but what works work. However I think you should import bootstrap into your nextjs app this way.
useEffect(() => {
typeof document !== undefined
? require("bootstrap/dist/js/bootstrap")
: null;
}, []);
I don't want to make this too long, so lets dive straight into creating the solution. First you have to create a custom function to close the offCanvas when you click your link.
const topicRef = useRef(null);
const closeOffCanvas = (event) => {
event.stopPropagation();
const bootstrap = require("bootstrap/dist/js/bootstrap");
var myOffcanvas = topicRef.current;
var bsOffcanvas = bootstrap.Offcanvas.getInstance(myOffcanvas);
bsOffcanvas.hide();
};
Now create your link like so and call the function we just created
<Link href={`/article/18004/close-bootstrap-5-offcanvas-in-next-js`} passHref>
<a href="#" onClick={closeOffCanvas}>navigate to page then close offCanvas</a>
</Link>
I hope this helps you

Related

Using Next router to link to a dynamically created page

Fairly new to NextJs - I am trying to link between a category index page and a dynamically created page, which is using getServerSideProps
I have created a product template page with the following path -
/products/[...product]
I am trying to link to it from the index page using this code, but it is not working
import { useRouter } from "next/router";
const router = useRouter()
const handleClick = () => {
const productUrl = `/products/${slug}`;
router.push(productUrl);
};
The following code does work, but is not very performant
const handleClick = () => {
const productUrl = `/products/${slug}`;
window.location.replace(productUrl);
}
Any ideas on how to implement dynamic pages with next/router would be appreciated
Generally, for accessibility reasons (and also to avoid perf/js issues like the one you're seeing), if a button press is meant to result in a page-change, you should use anchor tags.
In Next.Js to get performant routing, you wrap these tags in a Link:
import Link from 'next/link'
...
<Link href={`/products/${slug}`}>
<a> See details </a>
</Link>
This will then work with the dynamic slug from props.

Manually closing the calendar primereact

I'm using primereact version 6.2.1, While using the calendar from primereact i have enabled the option for showTime. This brings up a datePicker with an overlay blocking out the rest of the webpage. All this works fine. Except after a date and time are picked the only way to close the datePicker is to click somewhere else on the browser. Is there a way to close it manually ?
import React, { useRef } from 'react';
import { Calendar } from 'primereact/calendar';
const CustomCalendar = (props) => {
const cal = useRef(null);
const handleClose = () => {
cal.current.hideOverlay()
// if you're using touchUI option you have to hade it also ;)
cal.current.touchUIMask.style.display = "none";
};
return <Calendar
ref={cal}
{...props}
footerTemplate={(e) => <div className='footer-calendar'><button onClick={handleClose}>Done</button></div>}
/>
}
You can close overlay manually using ref, you can check this link
sandbox
or check the github link for more options
github
If you get a ref to your Calendar you can call calendarRef.current.hideOverlay();
I also opened this ticket: https://github.com/primefaces/primereact/issues/2685
Submitted this PR: https://github.com/primefaces/primereact/pull/2687

How to use useNavigate previous page without accidentally leaving my site

Problem: I'm trying to use useNavigate(-1) to go to previous page, but I just implement a way to people arrive in my SPA with a pasted link (or social media tho), so, when user tries to go back they leave my site xP.
Process: I could use useNavigate("/"), but this makes my page scroll to the top and I want to keep the previous users position, I rather not use a state with my scroll position, but if nothing else is possible or simple...
Context: is a restaurant menu ifood-like page, this problems occurs in product page and I want to go back to product list.
What I'm trying to achieve: some way to check if previous page is out of my domain and not go there, replacing with my root.
ps. I'm using "react-router-dom": "^6.0.0-beta.0"
In earlier versions of React Router DOM, there was a smarter goBack method, but in modern versions (including the v6 beta), you must use the fact that the location.key is "default" for the initial entry to the app's history.
I created an npm package that encapsulates this functionality in a simple React hook.
Install use-back
npm install use-back
Usage
import {useBack} from "use-back";
const BackButton = () => {
const {hasBack, handleBack} = useBack();
return (
<button type="button" onClick={handleBack}>
{hasBack ? "Go Back" : "Go Home"}
</button>
);
};
CodeSandbox Demo
Source Code
The source code is basically the following, which you can also include in your application.
const MagicalBack = () => {
const navigate = useNavigate();
const location = useLocation();
const hasPreviousState = location.key !== "default";
const handleClick = () => {
if (hasPreviousState) {
navigate(-1);
} else {
navigate("/");
}
};
return (
<button type="button" onClick={handleClick}>
{hasPreviousState ? "Go Back" : "Go Home"}
</button>
);
};
CodeSandbox Demo

React-router-dom Link open at the top of page

So I am feeling pretty dum to ask this but cannot find a straight answer to it.
Do I need to give any css parameter or directly to <Link> in order for the pages on my react app open at the top?
EDIT
So refraining, everytime I click on a <Link>element at my reactJs project, the Link opens a page at the middle of the screen, not a the top.
For example. I have this component
<li ><Link to={{pathname: "/product", state: {products}}}><i className="fa fa-search"></i></Link></li>
and when I click on in, it opens a new page/component but not at the top of the page. The user needs to scroll up in order to see the top, and i would like to open new pages directly at the top!
This can be done without installing any additional libraries. You can check the official example of react-router for scroll restoration here.
You can use library react-scroll, and detect when change pathname of location, scroll to Top like this
import { animateScroll } from 'react-scroll';
useEffect(() => {
animateScroll.scrollToTop({
duration: 0
});
}, [location.pathname]);
make scrollToTop function and use it in your link tag
const scrollToTop = () => {
window.scrollTo(0, 0)
}
when user click on any link our function will make our page scroll to top.
<li onClick={scrollToTop} ><Link to={{pathname: "/product", state: {products}}}><i className="fa fa-search"></i></Link></li>
I am using the class component for my react blog. The issue got solved by adding the following method and calling it inside componentDidMount().
scrollToTop = () => {
window.scrollTo(0, 0)
}
componentDidMount() {
this.scrollToTop()
}
You can check this code is working. Live example, Blog.
If you are using a function component, then same method you can use and call it inside UseEffect().

Nextjs causing hard refresh when i click in the Link

I have an app react using CRA, and I am trying to turn it into an SSR app using next. So, since there is little, the only things I changed were:
getInitialProps instead of useEffect and useState
Link from "next / link" instead of using react router dom
But when I click on the link, I get hard refresh.
Here is what is generating the link:
<Link href={post.meta.slug}>
<a>{post.title}</a>
</Link>;
I also tried with href={post.meta.slug} as={post.meta.slug}.
In my pages directory i have:
index.jsx
[slug].jsx
And this is how I get the post in [slug].jsx:
const PostPage = ({ post }) => {
return <Base>{post ? <Post post={post} /> : null}</Base>;
};
PostPage.propTypes = {
post: PropTypes.object,
};
PostPage.getInitialProps = async ({ query }) => {
const post = await getPostBySlug(query.slug);
return { post };
};
And so far I couldn't identify the error.
Here is the complete code: https://gitlab.com/flakesrc/blog-webstation-next
If you want to clone:
git clone https://gitlab.com/flakesrc/blog-webstation-next.git
cd blog-webstation-next
npm install
npm run dev
Have you tried this format for your Link?
<Link href='/[slug]' as={`/${post.meta.slug}`}>
<a>{post.title}</a>
</Link>
Here is a good example of this type of routing for dynamic pages as well as the section in the docs that also speaks to this a bit.

Resources