The website my team are developing is using Framer Motion. It seems that it won't work on Internet Explorer. I've tested it with IE 11. Searching for bug reports lead me to nothing.
When I tried to go in to your website on IE, https://www.framer.com/motion/, animations did not appear to be working either.
Has Framer Motion support for IE? If no, do you plan to implement it in a near future?
No support for IE11 now or ever I'm afraid. Time-permitting I hope to have a browser support list up in the docs, though it's basically all modern browsers.
I wouldn't bother supporting IE11, it's a dead end. The new Chromium-based Edge supports Windows 7 and newer. I'm sure Microsoft will be pushing it heavily to existing IE users via updates, notifications, banners on their web properties, and as a default in new installs of Windows. For corporate users, there is an "IE mode" built in for legacy sites.
Seems like the issue on frame.com/motion is caused by arrow functions - Is the problem you are using any methods in the library that can't be polyfilled?
@thebuilder I had to support IE11 on a project that used Pose, so I imagine the polyfills needed are similar. Here is what made IE11 work:
import "core-js/features/array/find";
import "core-js/features/object/assign";
import "core-js/features/promise";
import "core-js/features/string/ends-with";
import "core-js/features/symbol/for";
import "core-js/features/weak-set";
Thank you for your answers. My project also has to support IE. I added the polyfills and managed to make Framer Motion partly work on IE, but there were still a lot of issues. I will look at another option, probably remove animations completely on IE and keep Framer Motion for the modern browsers.
@mackan92 any information about what/how you added the polyfills? What issues are you seeing? Broken animations, or script errors?
Are you loading the the ES version of Framer Motion, or the ES5 version?
https://unpkg.com/browse/[email protected]/dist/
Most likely Webpack is loading the es version and just uses that uncompiled.
https://github.com/react-spring/react-spring/ has had the same issue with shipping ES6 bundle - They solved it by having you import the .cjs file instead.
If it's just a polyfill problem, I highly suggest everyone to use babel-preset-env or babel-plugin-transform-runtime with useBuiltIns and to not ignore node_modules, except a few like react-dom. You will thank me later.
Did anyone figure out how to get this working with Gatsby? Or could anyone point me in the right direction for how I could potentially support IE11 with Framer Motion / Gatsby. Thank you!
@samuelgoddard Gatsby shouldn't have any impact on wether Framer Motion works with IE11. Maybe you issue is a combination of three: 1) Framer Motion with IE11, 2) using JS polyfills with Gatsby, 3) Framer Motion page transitions in Gatsby.
@designbyadrian thanks for the reply, I don't really know where to start with debugging - I'm getting Object doesn't support property or method 'append' i IE11 when using framer motion page transitions, I've tried polyfilling it using polyfill.io but I then get an Object doesn't support this action error. Do you have any idea at all? Example site can be found here - https://prb-architects.netlify.app/
I keep meaning to add explicit docs about this to the repo but Motion 2
doesn’t support IE11 and Proxy is impossible to polyfill. I might be able
to add an extra entry point like import { ieMotion as motion } where you
accept ~1.5kb extra bundle size in exchange for IE11 support?
On Sun, 26 Jul 2020 at 15:17, Sam Goddard notifications@github.com wrote:
@designbyadrian https://github.com/designbyadrian thanks for the reply,
I don't really know where to start with debugging - I'm getting Object
doesn't support property or method 'append' i IE11 when using framer
motion page transitions, I've tried polyfilling it using polyfill.io but
I then get an Object doesn't support this action error. Do you have any
idea at all? Example site can be found here -
https://prb-architects.netlify.app/—
You are receiving this because you commented.Reply to this email directly, view it on GitHub
https://github.com/framer/motion/issues/364#issuecomment-663987020, or
unsubscribe
https://github.com/notifications/unsubscribe-auth/AB34WKTDG4IQCGWIAFY2J5LR5QUHTANCNFSM4JA5LZTA
.
@InventingWithMonster That would probably be the best of both worlds. I'm in a position where the product I'm working on is not going to be able to drop support for IE11 until 2021 at the earliest.
For future me, @samuelgoddard and anyone else Googling... even if you are using CRA or react-app-polyfill but have upgraded to framer-motion v2, you will be getting the IE console error of 'Proxy' is undefined in some chunk.js file and Object doesn't support property or method 'append'.
As Matt says, V2 doesn't work with IE so downgrading to [email protected] should get you back on track.
Thank you for working on this @InventingWithMonster! As much as I'd love to sunset IE11, we are also in a similar state and need to support it for a while. Looking forward to seeing what you come up with.
I might be able to add an extra entry point like import { ieMotion as motion } where you accept ~1.5kb extra bundle size in exchange for IE11 support?
@InventingWithMonster☝️ That would be awesome.
Sadly, IE 11 support is critical for us. We're an enterprise company with a surprising number of clients with a death grip on IE 11. We love framer motion ❤️, and would love continued support. We'll pay the extra 1.5kb gladly.
Will roll back to 1.x.x for now.
@InventingWithMonster Any progress with IE11 support?
Hey,
I'm using version 2.6.13, when I'm loading my app in IE 11 the browser crash and I get an error - "Proxy is undefined".
did anyone encounter this problem and found a way to deal with it?
Lowering the version to 1.x.x isn't an option for me
@InventingWithMonster Is there any chance we could reopen this issue? The op closed it, but clearly there is a lot of critical interest in IE11 support, even if it results in a larger bundle size. Without it, many of your enterprise consumers will be put in a tough position.
Yep this is worth keeping open imo, I will manage to take a look in the coming weeks
The linked PR ^ shows a new API that will help you create a replacement for motion that doesn't use Proxy. Please note that this doesn't constitute IE11 support, for instance future versions of Motion may require new polyfills, or make others unnecessary.
However this is a nicer solution IMO than a separate legacy entry point, both in terms of code complexity on our side (= no dusty API corners to break for you) and also it will actually be slightly smaller than importing motion itself.
This is great - How do you envision it actually being used? Should we create all the HTML tag's we'd want to support in the custom motion and share that instance throughout the application?
import { createDomMotionComponent } from 'framer-motion'
/** IE 11 supported version of the motion component */
export const motion = {
div: createDomMotionComponent("div"),
span: createDomMotionComponent("span") ,
svg: createDomMotionComponent("svg") ,
}
Yeah exactly this ^
Just to improve upon it, a check for Proxy support could be added, so it only uses the fallback if needed:
Not recommend - See below
import { motion, createDomMotionComponent } from 'framer-motion
/** IE 11 supported version of the motion component */
export const motion = typeof Proxy === 'undefined' ? {
div: createDomMotionComponent("div"),
span: createDomMotionComponent("span") ,
svg: createDomMotionComponent("svg") ,
} : motion;
I would recommend against that approach as Motion's motion isn't necessarily the same as the user-generated one leading to obscure runtime errors.
You'd be writing in an environment with Proxy, so your module would export motion. So you go ahead and use motion.header or motion.custom(Component), but neither of these have been implemented. You ship it, it works in all testing environments, but it'd only be someone using it in IE11 who would get the runtime error. It's probably safer to use your custom motion component always, so if you use an undefined component it breaks for you in dev.
Tried it on our production website, and it's working great. Did have to modify the typescript types to get them to match, since it createDomMotionComponent doesn't match the exported motion types.
// createDomMotionComponent
ForwardRefExoticComponent<MotionProps & React.RefAttributes<unknown>>
// motion.div type
ForwardRefComponent<UnwrapFactoryElement<ReactHTML[K]>, HTMLMotionProps<K>>
The result is the returned type doesn't contain the HTMLProps. Could it make sense to reuse the UnwrapFactoryElement and UnwrapSVGFactoryElement types to create the correct types? The function gets the DOM element as a string, so should be possible to map the same way.
I've generated my own list of ValidMotionTypes by reusing the exported HTMLMotionComponents. Could be optimized further, but works for now.
import React from 'react';
import {
createDomMotionComponent,
motion as originalMotion,
} from 'framer-motion';
import { CustomDomComponent } from 'framer-motion/types/render/dom';
import {
HTMLMotionComponents,
SVGMotionComponents,
} from 'framer-motion/types/render/dom/types';
type CustomMotionType = {
custom: <Props>(
Component:
| string
| React.ComponentClass<Props, any>
| React.FunctionComponent<Props>,
) => CustomDomComponent<Props>;
};
type ValidMotionTypes = CustomMotionType &
Pick<
HTMLMotionComponents & SVGMotionComponents,
// List all the exported HTML/SVG tags here. This ensures
'div' | 'span' | 'button' | 'a' | 'article' | 'header' | 'svg' | 'path'
>;
export const motion = {
div: createDomMotionComponent('div'),
span: createDomMotionComponent('span'),
button: createDomMotionComponent('button'),
a: createDomMotionComponent('a'),
article: createDomMotionComponent('article'),
header: createDomMotionComponent('header'),
svg: createDomMotionComponent('svg'),
path: createDomMotionComponent('path'),
custom: originalMotion.custom,
} as ValidMotionTypes;
// re-export everything
export * from 'framer-motion';
Tried this fix/solution in a clean CRA with polyfills for IE11 but can't make this to work. As soon as I import import { createDomMotionComponent } from 'framer-motion' without even using it, I get an error that Proxy is not defined when running the code in IE11 browser. Is there something else more than correct polyfills to make this to work?
@linusklingzell Have you enabled code splitting in your bundler?
@mattgperry I am guessing this doesn't polyfill motion.custom? I see the createMotionProxy function being bundled in, even with above workaround. I am also using CRA + ie11 polyfills.
Cheers!
Tried code splitting as you suggested @mattgperry with dynamic imports but I still get the same error
Hello,
I've just run into this problem. Chakra-ui uses the new framer-motion but we still want to support IE11 until it is no longer profitable.
My plan is to resolve my module to a wrapper that can export a non-proxied equivalent of motion if I detect the need to like @thebuilder suggested.
However, I was wondering why the index-legacy.ts was removed:
https://github.com/framer/motion/commit/b4319c78fb4bde28ce0d2a8008df48d7e3fd1c8b
Rather than having to keep a separate list of modules, I would like to import the defaults and custom, which seemed to be exposed previously, but is now removed. Could you maybe explain why this functionality is gone or its downsides? @mattgperry
Thanks!
Reopening as there's clearly some further things to figure out
After working on it yesterday, I was able to get the wrapper to work, with the current framer-motion package.
The wrapper file (client/framer-motion-wrapper.js in my solution):
import { motion as origMotion, createDomMotionComponent } from '../node_modules/framer-motion';
import { proxyDefined } from './clientState';
// fragile copied from internal framer-motion supported-elements.ts
import { htmlElements, svgElements } from './framer-motion-supported-elements';
// Adapted from https://github.com/framer/motion/commit/b4319c78fb4bde28ce0d2a8008df48d7e3fd1c8b
const createNonProxyMotion = () => {
let motionProxy = {
custom: (component) => {
createDomMotionComponent(component);
},
};
motionProxy = htmlElements.reduce((acc, key) => {
acc[key] = createDomMotionComponent(key);
return acc;
}, motionProxy);
motionProxy = svgElements.reduce((acc, key) => {
acc[key] = createDomMotionComponent(key);
return acc;
}, motionProxy);
return motionProxy;
};
export const motion = proxyDefined ? origMotion : createNonProxyMotion();
export * from '../node_modules/framer-motion';
Note, because motion calls to Proxy on module initialization, you STILL need a proxy-polyfill before your module-wrapper, I have a main polyfill that is included at the top of my entry-point with this logic:
// determine the state of the client before polyfilling
import { proxyDefined } from './clientState';
// ...Other polyfills
// Example: immer assumes es6 if polyfill is defined - keep this in mind if other libraries are failing after polyfilling
import { enableES5 } from 'immer';
// We have to include this for now, since framer-motion requires the Promise call immediately
import 'proxy-polyfill';
if (!proxyDefined) enableES5();
The clientState.js is basically a copy-paste of the proxy-polyfill switch:
const hasProxy = (scope) => !!scope.Proxy;
// Using the same Proxy polyfill checks as proxy-polyfill
export const proxyDefined = hasProxy((typeof process !== 'undefined'
&& {}.toString.call(process) === '[object process]')
|| (typeof navigator !== 'undefined' && navigator.product === 'ReactNative')
? global
: self);
Finally, whatever your packing solution, you will want to perform a module replacement. Here's the example with webpack:
config.plugins.push(new webpack.NormalModuleReplacementPlugin(
/^framer-motion$/, path.resolve(__dirname, 'client/framer-motion-wrapper.js'),
));
Hopefully this helps in both the bug-fixing and anyone else hoping to still support IE11. If you find a better solution, I would love to hear!
Greetings! I've started a small project with framer motion. I didn't know it doesn't support IE. Tried using createDomMotionComponent instead of motion but the animations go into a loop and I couldn't figure out why. With motion works fine but the fix doesn't. Also, the types don't match as @thebuilder commented.
@rr-justin-hanselman
I have tried to do exactly as you and I have managed to make the wrapper work. Unfortunately, I am still getting "'Proxy' is undefined" on IE. The polyfill you are using, 'proxy-polyfill', is it this one? https://www.npmjs.com/package/proxy-polyfill
Update: Now I managed to import the polyfill mentioned above correctly. It works with IE 11!
I imported the polyfill like this:
import 'proxy-polyfill/proxy.min.js';
I use the latest version of Framer Motion (2.9.4).
@mackan92 Would you mind posting the files and changes you have made to make it work in IE 11?
The polyfill works, but I'm having troubles copying the additional files (framer-motion-supported-elements.ts, clientState.ts etc.) together.
Most helpful comment
I keep meaning to add explicit docs about this to the repo but Motion 2
doesn’t support IE11 and Proxy is impossible to polyfill. I might be able
to add an extra entry point like import { ieMotion as motion } where you
accept ~1.5kb extra bundle size in exchange for IE11 support?
On Sun, 26 Jul 2020 at 15:17, Sam Goddard notifications@github.com wrote: