ReactJS: How to properly link to a download file? - javascript

I have a manual.pdf file that I need to attach to my document.
The conventional wisdom would be to link the file source in the href attribute of an <a> tag:
<a href="../assets/img/manual.pdf" download>Manual</a>
React seems to not like it, I assume. Failed-No file error is given upon click on the <a> tag.
When it is an <img> tag with a local file, I would import the source import logo from '../assets/img/logo.svg';, then pass it to the src attribute like so <img src={logo} alt="brand logo" />.
I tried it - no use.
giving the absolute path - no use.
giving a relative path - no use.
It seems that it does not work the same way with <a> tags.
How do I properly link local files in a React Project?
P.S. I have heard of React routes, but I am not linking to any page, it is for downloading a file.

Try this
<Link to="/files/manual.pdf" target="_blank" download>Download</Link>
Where /files/manual.pdf is inside your public folder

Try this one https://www.npmjs.com/package/file-saver (FileSaver.js)
//function for saving file
const saveManual = () => {
fileSaver.saveAs(
process.env.REACT_APP_CLIENT_URL + "../assets/img/manual.pdf",
"manual.pdf"
);
};
//button for calling
<button onClick={saveManual}>
Manual
</button>

Related

NextJS automatically replace <img/> tag to <Image/> Component

I have the Problem, that I fetch HTML (and md) from a headless CMS (Directus).
The Problem is that the Images are not optimized.
How can I automatically replace all fetched tags with Next`s Image-Component?
This is how I fetch the Html Code:
<div dangerouslySetInnerHTML={ {__html: data.path} }></div>
This is how I fetch MD:
<ReactMarkdown rehypePlugins={[rehypeRaw]}>
{data.path}
</ReactMarkdown>
Usually code editors have such functionality. Find out for yourself in the editor how you can do this
If I understood your question properly, you are saying your tags are automatically getting converted to next/Image component ?
If that's the case all you need to do is add domain names from of IMG src url to next config file you can read more about it here: https://nextjs.org/docs/basic-features/image-optimization#domains

how to use images in reactjs

Here is my code.
I have an images folder inside the "src" folder and I want to use the images inside of my components/Myapp.component.js
import React from 'react';
import imageOne from '../img/cool-img.jpg';
function Myapp() {
return (
<div className="myapp">
<h1>import image<h1>
<img src={imageOne} alt="import-img" />
<h1>relative-path image</h1>
<img src="../img/cool-img.jpg" alt="relativepath-img" />
</div>
);
}
export default MyApp;
My problem is that the first import image works fine but the second relative path image does not work.
There are some common ways to import images in the ReactJs application. for such cases that images have separated server, it's so simple just call images like below:
<img src="https://images.cdn.com/sample-image.png" alt="sample-image" />
But if the images are for the application not for a show to the users, like images of UI design, there are two common ways:
Use copy-webpack-plugin and put all photos inside a folder then after build and serve, you should serve this folder and then you can call them from your link(eg: assume we run the project on the localhost:3000):
<img src="https://localhost:3000/sample-image.png" alt="sample-image" />
Just like your first trick, put all photos inside a folder and import them inside each component you need, then use it:
import sampleImage from '..[pathToAssets]/assets/imgs/sample-image';
~~~
<img src={sampleImage} alt="sample-image" />
I hope this answer helps you.
This is not working because <img src="../img/cool-img" alt="relativepath-img" /> image src is not resolved using Webpack file-loader, when you use import statement for a file, it will be checked first by Webpack and it will use the appropriate loader for the file type, in your case its an image so it will use file-loader, it will then handover the responsibility for it to handle the resolve of your file path,
If for example do a console.log(imageOne) it will log a path for your image, based on your public file path specified in your Webpack config file.
<img src="../img/cool-img" alt="relativepath-img" /> on the other hand will be printed as is since it written inside JSX code and it will not resolve the real path for your public folder.
So you should be using the first way (importing files) to resolve your files/images path.

Render an SVG icon inside a button?

I have an SVG in a folder icon.svg, I'm trying to render it in a button along with text. Specifically, it's the Google icon and i'm trying to render it next to some text that says "SIGN IN WITH GOOGLE"
I'm importing the SVG as is and trying to pass it next to the button but, the file path is rendering instead:
function App() {
return (
<div className="App">
<button>{SVG}SIGN IN WITH GOOGLE</button>
</div>
);
}
That renders a button that says /static/media/Icon.a1611096.svgSIGN IN WITH GOOGLE
How is one supposed to render the icon inside the button properly?
EDIT: I've been messing with the icon and the button and got close:
https://codesandbox.io/s/10k7rr3rp4
First you have to save the icon in assets folder. Then import it into the component which you want to use in
import {ReactComponent as Logo} from '../../assets/google.svg';
Now you can use it like a component
<button>
<Logo className='logo' /> Sign in with Google
</button>
You can use the require function as follows:
<button><img src={require(SVG)} alt="test" />SIGN IN WITH GOOGLE</button>
another solution could be to use styled-components with ::before pseudo element.
i just moved the images folder to the public folder.
live example

Vue project can't find image when using <a href> but can find it when using <img>

I have this Vue project. All I've done is run vue create foo and removed all the pre-created code that comes in the src folder when you run that command. I then added an image to the src folder and created my own App.vue, this is all I've written in it.
<template>
<div>
<img alt="Vue logo" src="./foo.png">
<a href="./foo.png" download>foo</a>
</div>
</template>
<script>
export default {
}
</script>
When I then try it out with npm run serve the website displays the image perfectly fine, but the download link does not work. It says the server doesn't have the requested file or something.
Vue loader automatically transforms img src attributes in templates into webpack module requests, but by default it doesn't do the same for links.
If you need to link directly to a file, you can put it in the public/ directory to bypass webpack (using a path relative to that directory -- i.e. for a file in public/foo/bar.jpg you'd use <a href="/foo/bar.jpg">)
Alternatively, you can leave the file where it is, and tell webpack to transform <a href> urls into module requests, just as it does image src urls, by changing the transformAssetUrls options:
/* Add to vue.config.js */
module.exports = {
chainWebpack: config => {
config.module
.rule("vue")
.use("vue-loader")
.loader("vue-loader")
.tap(options => {
// modify the options...
options = Object.assign(options, {
transformAssetUrls: {
a: "href"
}
});
return options;
});
}
}

How to get image from public folder without using Webpack

I have read a lot of posts on getting image from the public folder with Webpack. However, is there anyway to do so without a Webpack?
My code structure:
./public/logo.png
./src/../source_file.js (which renders an <img> and that needs to be pointed to the logo image
I tried import img from './logo.png' but that is not working. Also tried relative path but reactjs is preventing me from importing anything outside src folder.
As long as your package.json is at the root, this will work:
import logo from '../../public/logo.png';
const MyComponent = () => (<div>
<img src={logo} alt={"logo"} />
</div>);
export default MyComponent;
Otherwise, assuming you are copying your /public folder to the root of your webserver, you can also simply do <img src="/logo.png" alt="logo">
I finally use window.location.origin + "logo.png". Posted here in case anyone want to have a try.

Categories

Resources