Reputation: 139
I want to add background video, format mp4, but NextJS shows error:
./public/video/ocean.mp4 1:0
Module parse failed: Unexpected character '' (1:0)
You may need an appropriate loader to handle this file type, currently
no loaders are configured to process this file. See
https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)
import React, {useEffect, useRef} from "react"
import Layout from "../components/webSite/layout";
import backgroundVideo from "../public/video/ocean.mp4"
const Home = () => {
const videoRef = useRef()
useEffect(() => {
setTimeout(()=>{
videoRef.current.play()
},5000)
}, []);
return <Layout title={"Home"}>
<video
ref={videoRef}
controls
width="250"
loop
muted
style={{
position: "relative",
width: "100%",
height: "15rem",
left: 0,
top: 0,
}}>
<source src={backgroundVideo} type="video/mp4"/>
</video>
</Layout>
}
export default Home
Upvotes: 13
Views: 15812
Reputation: 2253
Contrary to the other answers, it is not inefficient to import an .mp4
(using the right loader) and it doesn't require a Next.js-specific plugin.
Using file-loader
, webpack will give you a URL as the import of your .mp4
. webpack simply copies the .mp4
to the output directory (not in the bundle) and returns a relative URL to that. It will be requested normally when you use it in a <video>
element.
To use file-loader
for .mp4
s, you can add a webpack()
callback to your next.config.js
like the below.
export default {
webpack(config, { isServer }) {
const prefix = config.assetPrefix ?? config.basePath ?? '';
config.module.rules.push({
test: /\.mp4$/,
use: [{
loader: 'file-loader',
options: {
publicPath: `${prefix}/_next/static/media/`,
outputPath: `${dev ? '' : '../'}${isServer ? '../' : ''}static/media/`,
name: '[name].[hash:8].[ext]',
},
}],
});
return config;
},
};
Note: If you're using an older version of Next.js, you may need this outputPath
config instead:
outputPath: `${isServer ? '../' : ''}static/media/`,
Then simply import your .mp4
and use it in a <video>
element
import myvideo from './myvideo.mp4';
export default function MyVideo(){
return <video>
<source src={myvideo} type="video/mp4"/>
</video>;
}
If you're using TypeScript, you'll also want to add a declaration for the file extensions that you're loading with file-loader
. This should go in a .d.ts
, Next.js recommends (scroll down to find the info box mentioning it) making videos.d.ts
and then adding it to your TS config include
property.
// videos.d.ts
declare module '*.mp4' {
const path: string;
export default path;
}
next-videos
does under the hood, with fixes for the production buildnext-image-loader
, which is included internally in Next.jsnext-file-loader
is another loader with a similar approach which can do this for multiple file typesUpvotes: 12
Reputation: 51
If the first answer won't work then try this:
Install a Package called
next-videos
After Installing go to your next.config.js File in your project and do this:
const withVideos = require('next-videos')
module.exports = withVideos()
Important is that after editing your config file you have to restart the server if you don't it won't work either.
In your File, you have to use require()
in your component
For Example like this:
export default () => (
<div>
<video src={(require('./video.mp4'))}/>
</div>
)
All Information are used from npm.js website:
https://www.npmjs.com/package/next-videos
Upvotes: 5
Reputation: 6087
Everything that you import
in React actually needs a webpack loader that understands the format.
MP4 is not one of those formats. Even if it was, importing an entire video file would be horribly inefficient :-)
Solution: Don't import the video file, instead reference it as an external file that the browser loads over http like any other media file. All files you put in /public
can be referenced below the top folder of you web site:
<source src="/video/ocean.mp4" type="video/mp4"/>
Upvotes: 19