What is the best way to integrate Nextjs Link Component with framer motion in a Typescript environment?

Description

I am trying to use Framer Motion to animate a Next.js Link component in a TypeScript environment, but I keep encountering a type error:

Property 'Link' does not exist on type '(<Props extends {}>(Component: string | ComponentType<PropsWithChildren<Props>>, customMotionComponentConfig?: CustomMotionComponentConfig | undefined) => CustomDomComponent<...>) & HTMLMotionComponents & SVGMotionComponents'. Did you mean 'link'?

Code

Below is the code snippet for the component I am working on.

export default function Button({ href, text, type, ...props }: ButtonTypes) {
  console.log(styles);
  if (href) {
    return (
      <motion.Link
        href={href}
        type={type}
        className={`${styles['neon-button']} focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-aquamarine`}
        {...props}
      >
        {text}
      </motion.Link>
    );
  }
  return (
    <motion.button
      whileHover={{ scale: 1.1 }}
      whileTap={{ scale: 0.9 }}
      type={type}
      className="neon-button focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-aquamarine"
      {...props}
    >
      {text}
    </motion.button>
  );
}

Expectations

I have successfully added animation properties like whileHover and whileTap to the component, but I need to resolve the type error to ensure smooth functionality.

Answer №1

To implement Framer motion on a Component, you can wrap it in the motion() function.

const Component = React.forwardRef((props, ref) => (
    <div ref={ref} />
))

const MotionComponent = motion(Component)
const MotionLink= motion(Link)

Explore Framer Custom Component

If you prefer alternatives, here are some workarounds:

Workaround 1: You can wrap your Link component in a div and apply Framer motion to the wrapper div.

<motion.div
   className={styles.linkWrapper}
   //add your motion props here
>
  <Link href="#"> Lorem </Link>
</motion.div>

--

Workaround 2: Instead of using <Link>, you can utilize <motion.a> and utilize the useRouter hook for Link functionality on the a tag.

Example:

const router = useRouter()
 <motion.a
    href="/contact"
    onClick={(e) => {
       e.preventDefault();
       router.push("/contact");
    }}
    className={styles.navLink}
 >
    Lorem
</motion.a>

For more information, visit: Official Next useRouter Hook documentation

Answer №2

An issue in TypeScript arises from the absence of <motion.Link> in Motion's API. Motion solely supports DOM primitives such as <a> and <button>. This clarifies why motion.button functions smoothly while Link is recognized as a NextJS component.

Refer to for guidance on crafting a customized Motion component that encapsulates NextJS' Link component. This approach effectively eliminates the TypeScript error.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue with handling a Promise Rejection error in a React/Next.js project while working with the openAI API

Currently, I am in the midst of working on a React/Next.js project where I have come across an error regarding Unhandled Promise Rejection within my code. Resolving this issue has proven to be quite challenging. Here are the specifics of the problem: Erro ...

Angular's custom validator consistently returns a null value

I need help with validating the uniqueness of a username field in a form where an administrator can create a new user. I have implemented a uniqueUserNameValidator function for this purpose, but it always returns null. I suspect that the issue lies in the ...

Is there a way to showcase just the month in one spot when presenting data using Angular 13?

Just starting out with Angular and facing a challenge in the Milestone section. There is a loop for displaying years and months, but I need to ensure that the month name is displayed only once for each specific year. Can someone provide me with a possible ...

Translation with React-i18next will occur once the component has been re-rendered

I have a webpage that supports both English and French languages using Next.js and react-i18next. The issue I am facing is that when I set the language to French (Frn) and refresh the page, it still displays English content. I noticed two peculiar things ...

An issue occurred with npm resulting in exit code 2. The error is as follows: Command was unsuccessful: node_modules/.bin/vsce package --no

Here is the specific error displayed in cmd: TS1323: Dynamic imports are only supported when the '--module' flag is set to 'es2020', 'esnext', 'commonjs', 'amd', 'system', or 'umd'. E ...

Mastering CSS: Optimizing Div Placement Across Sections

I am currently working on developing a sleek and modern landing page with multiple sections, each designed to catch the eye. This style is all the rage at the moment, featuring large headers, ample padding, bold text, and a visually appealing divider betwe ...

Is importing all models into every component considered poor practice?

At my workplace, there is a practice in the legacy code where every single model is imported into all components, regardless of whether they are needed or not. For example: import * as models from '../../view-models/models' ....... let parrot: m ...

Mapping out the structure of a Next.JS site with multiple languages and domains

It appears that I need to have sitemap-en.xml and sitemap-de.xml in the root directory of my project. Among all the possible solutions, I am intrigued by the concept of utilizing rewrites and generating sitemaps with the help of /api //next.config.js const ...

Can you explain the distinction between @types/material-ui and the official @mui/types bundle?

When it comes to npm packages, I came across @types/material-ui and @mui/types. I'm aware that the former is backed by the Definitely Typed community, but what's the reasoning behind its existence when an official types package already exists? D ...

The parameter type 'Event' cannot be assigned to the argument type

edit-category-component.html: <custom-form-category *ngIf="model" [model]="model" (onSaveChanges)="handleChanges($event)"></custom-form-category> <mat-loader *ngIf="!model"></mat-loader> edi ...

Is Validators.required a necessity in Angular 2?

Is there a way to dynamically require a form field based on conditions? I created a custom validator, but the conditional variables passed to it remain static. How can I update these conditional values within the custom validator function? Is it possible t ...

Angular Material: Enhanced search input with a universal clear button

After searching for a cross-browser search control with a clear button similar to HTML5, I found the solution rendered by Chrome: <input type="search> The code that gave me the most relevant results can be found here. I used the standard sample w ...

Guide on dividing a URL string in Angular framework

Is there a way to include a value directly in the URL, like so: http://example.com/component/july2021 I need to extract july2021 from the component and separate it into "july" and "2021". How can I achieve this? ...

The communication between the Next.js and Node.js servers is being obstructed as the request body fails

Could you lend me a hand with this issue? Here is the function being called: function apiCreate(url, product) { console.log('Posting request API...' + JSON.stringify(product) ); fetch(url, { dataType: 'json', method: 'post ...

"Encountering issues with Firebase deployment related to function-builder and handle-builder while working with TypeScript

I encountered 4 errors while executing firebase deploy with firebase cloud functions. The errors are originating from files that I didn't modify. node_modules/firebase-functions/lib/function-builder.d.ts:64:136 - error TS2707: Generic type 'Req ...

Collaborative React front end elements are now housed in their own TypeScript project within Visual Studio 2017

In Visual Studio, our project structure includes the following: PublicClient, Admin, and SharedComponents. The SharedComponents project is essential because many components are shared between our client and admin interface. This structure is based on the f ...

executing a hook within _app.tsx in Next.js

The issue I'm facing involves the rendering of a hook that helps determine if my components are within the screen's view to trigger animations. This hook is executed in _app.tsx, however, it doesn't run when switching to another page. Oddly ...

using a function as an argument in the map method within a React component

I have a challenge where I am trying to display blog posts retrieved from my database. However, for each item, I also need to execute a download image function. I attempted to include the function within the .map function but encountered some errors. I am ...

typescript error: passing an 'any' type argument to a 'never' type parameter is not allowed

Encountering an error with newUser this.userObj.assigned_to.push(newUser);, receiving argument of type 'any' is not assignable to parameter of type 'never' typescript solution Looking for a way to declare newUser to resolve the error. ...

Navigating to a new page in NextJs using route.push() in a

I'm currently learning Next.js and practicing, but I've run into an issue. I'm hoping to find someone who can help me diagnose the problem. Below is my route.push() function: onClick={(e) => { const query = { oid: data.oid, ...