React-to-print: Styles not included in print

Created on 9 Apr 2018  路  61Comments  路  Source: gregnb/react-to-print

I'm using create-react-app and CSS classes. The styles are not loaded on the print media.

bug

Most helpful comment

Hey @gregnb this is working great for me on a project in a development environment, but when we do a production webpack build the styles seem to be missing.

All 61 comments

Hey @rrsilaya would you mind sharing your repo so I could take a look?

Hey @gregnb this is working great for me on a project in a development environment, but when we do a production webpack build the styles seem to be missing.

Hey @ShawnKoga would love to nail down the source of issues anyway you can provide a simple repo to look at?

I'm checking the source map files for the production files real quick to see if I can find out what is going on.

Ok, sounds good. If you don't see an obvious error any other items you can list to paint a picture of what your environment looks like would be helpful. It's my fault for not filling out the ISSUE template and it's on my todo list

I'm having some issues with this as well, currently. I wish I could send you my code but it's in a fairly complicated App and copying and pasting code wouldn't be very feasible. I am using React Native for Web, not sure if that makes a difference.

I can say that I have discovered if I use inline styles then they seem to get passed through to the printed content, but if I use a styles constant they do not. For example:

Within my ComponentToPrint component the following works:

<Text style={{ fontSize: 35 }}>Hi There</Text>

but the following does not:

<Text style={styles.bigText}>Hi There</Text>

const styles = StyleSheet.create({
    bigText: { fontSize: 35 }
});

I know that's not proper code as there's no Component or render method or anything, but hoping you get my drift.

@dereksweet Understood. To be honest I've never tested this using React Native for web so I don't know if that could cause any issues

Will keep mucking around and let you know if I get it working. Is a great tool, exactly what I'm looking for as I'd rather not make an entirely new endpoint just for the printed version of a "frame" on my page. Would be amazing if I could just throw a ref into the component and then make the print button use your tool.

Yep, exactly why I wanted to make it. I saw a solution but it relied on an iframe. Where there's smoke there's fire and there's some uncovered bug I have to nail down. Need more info so hopefully this thread will point us in the right direction.

I'm going to try to play around some more tonight and see if I can trigger this issue.

I just took a look at your code and saw that it selects any elements that match style and link[rel="stylesheet"] so I was like "OK, I'll just go see what kind of element these React Native fr Web stylesheets make and then I can add that selector to the list".. After 15 minutes I still cannot see where the heck this style is being defined in the actual generated HTML, so I'm gonna not blame your component and instead blame the complexity of React Native Web :)

@dereksweet Bummer! If you find anything useful let me know :)

Brought it up with our frontend guy this morning and even he does not know how React Native for Web stylesheets end up getting rendered in the HTML, so just made a new endpoint for the printed content. Oh well, thanks for writing the component though, I'm sure it will come in handy one day. If you ever get it working for RN for Web let me know!

Hi, if you need a repo to look at I made this one:

https://github.com/ishraqiyun77/print-issue

Well, this at least reflects my use case.

If you change the className='printtest' to style={{ color: 'red' }} the color is retained in printing. Also note, this example does use bootstrap.css and I have removed anything related to @media print from boostrap.css.

The probably is the same no matter what solution I try: external styles are not being applied in printing but inline styles are. I've pretty much exhausted every option I can think of and react-to-print was the the last on my list to check out. Really not sure what a solution is, but it has stopped me dead in my tracks for the last week and half. SO hasn't really been able to help me either.

Also, tried everything on this list:

https://stackoverflow.com/questions/30135387/how-to-print-react-component-on-click-of-a-button/?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

Ok, thanks for supplying the repo. I'll take a look into it!

@ishraqiyun77 thanks for providing this repo. The issue appears to be from the fact that if someone is providing CSS with a relative path it is not setting up the proper relative link in the print window. I will address this tonight.

I will make a change where if a relative path is detected we will provide the proper qualified path into the print window for that given stylesheet

I've published a new version (1.0.15) that should resolve @ishraqiyun77 issues and maybe some others on this thread

@gregnb any change to get it published on npm? I'm experiencing the same issue as OP.

Print React components in the browser

Latest version: 1.0.15

Also very useful component, thanks for your work.

@nvma Should be up there as 1.0.15. I screwed up and meant to say 1.0.15

@gregnb Aww, too bad for me. So I've poked around and indeed <link href="main.css" rel="stylesheet"> doesn't work, but <link href="/main.css" rel="stylesheet"> works.

So just to make sure,

new MiniCssExtractPlugin({
  filename: '/[name].css',
}),

This kind of solves it, but I think it could be easily fixed by prepending slash when reading link for the DOM.

@nvma Just published 1.0.16 that should resolve the missing slash issue

Hi,
I still can't get this to copy styles over. Is that confirmed working for anyone else?

Actually, it is working in the repo I made, but not in my actual app. I'm thinking that might be due to the .scss import being on the parent component... but wouldn't think that should matter since all of the SCSS is converted to CSS which is read in from the index.html. Going to test it out some more...

Had this issue too. To have it working in chrome:

The issue is this line: https://github.com/gregnb/react-to-print/blob/d79b7fcb6f0644ee6ce4547e5454abdfcf7975a1/src/index.js#L94

Before:

let newHeadEl = printWindow.document.createElement(node.tagName);

After:

const doc = windowRef.contentDocument || windowRef.document;
let newHeadEl = doc.createElement(node.tagName);

Also, if you are using webpack if you have a blob it won't append that file: so i had to add logic to line:

Before:

https://github.com/gregnb/react-to-print/blob/master/src/index.js#L106

After:

            if (
                attr.nodeName === 'href' &&
                /^https?:\/\//.test(attr.nodeValue) === false &&
                /^blob:/.test(attr.nodeValue) === false
            ) {
                const relPath =
                    attr.nodeValue.substr(0, 3) === '../' ? document.location.pathname.replace(/[^/]*$/, '') : '/';

                nodeValue = document.location.protocol + '//' + document.location.host + relPath + nodeValue;
            }

@chrisjlee thanks for finding these flaws. Would you like to send in a PR?

Sure i'll try to put in a MR this weekend.

@chrisjlee I went ahead and added those changes myself in hopes that it will help some others here. They are now published. Thanks for sharing that information!

I upgraded react-to-print to 1.0.17 .this issue still exists.
npm start is ok. but after npm run build,open index.html cannot print css.
I used css like this:
'import './index_info.css';' on the head of js code.

@downup2u can you share a repo to download and see your issue?

I'm in the same boat, although i note that some of the CSS is coming through.
Fonts - everything works -> colour, weight, size
Borders - everything works -> colour, weight
background colour -> nothing
div sizes -> width appears to be ok, but height is all wrong.

So the css is getting through, but is just not interpreted fully.

--UPDATE--
If I set closeAfterPrint = {false}, I can see that it does indeed the CSS - just the height of divs and margins/padding look messed up (most likely due to a css that uses % rather than px for scaling). The background colour comes through on the new window, but not on the PDF view... this might be a chrome thing?

--UPDATE--
Firefox appears to have the correct formatting of everything in the new window, although background colours are still missing. I assume this means there's not a problem with this package, but rather an issue with the way the CSS background colours are dealt with by browsers?

--UDATE--
So I needed to ensure I use firefox and also use the dreaded !important on anything that has a background colour for printing. I also added
@media print{ body{ -webkit-print-color-adjust: exact; } }

And it all works just fine. Annyoing, but it works.

I'm having a similar issue on 1.0.19,

Webpack (ExtractTextPlugin) is generating my link tags in this format:
<link href="/app.bundle.48f0c92bd8ec03b6a1ff.css?13f2c6b6b37708020514" rel="stylesheet">

But ReactToPrint brings them in as:
<link href="https://mydomain.com//app.bundle.48f0c92bd8ec03b6a1ff.css?13f2c6b6b37708020514" rel="stylesheet">

If I remove the extra slash from this ReactToPrint generated style path, then the styles work.

Not working for me. Using 1.0.19 version. Interesting is it works perfectly on development while on production all styles are missing. I am using create-react-app. I have not ejected.

1.0.20 fixed my issue, thanks guys!

I'm using create-react-app, styled-components, and [email protected]. In development, the styles appear perfectly in the print window, however, in production, they are completely lost.

Any ideas?

@jmpolitzer Can you share your package.json? I'm going to recreate some apps with create-react-app seems like a lot of issues stem from it. I want to dive deeper in what is going on. When you mean production do you mean NODE_ENV=production or literally pushing out to your production server?

@gregnb Thanks for quick reply! By production, I'm referring to building the create-react-app and deploying out into the wild. In my case, I'm using Github Pages. Here's my package.json:

{
  "name": "resume",
  "homepage": "https://jmpolitzer.github.io",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "polished": "^1.9.3",
    "react": "^16.4.1",
    "react-dom": "^16.4.1",
    "react-icons": "^2.2.7",
    "react-live": "^1.10.1",
    "react-scripts": "1.1.4",
    "react-to-print": "^2.0.0-beta-1",
    "react-tooltip": "^3.6.1",
    "react-transition-group": "^1.2.1",
    "react-typist": "^2.0.4",
    "styled-components": "^3.3.3"
  },
  "scripts": {
    "predeploy": "npm run build",
    "deploy": "gh-pages -b master -d build",
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "devDependencies": {
    "gh-pages": "^1.2.0"
  }
}

@jmpolitzer Can you first try taking debug={false} off and pushing to prod? let me know. I see an issue around that I need to take care of on my end since this no longer will pop up a window in beta when turning debug on it will stop printing entirely

Sorry @jmpolitzer confusing this with another person's create-react-app issue. You probably didn't have debug={true} turned on anyway. Since it's a public page would you mind sharing the source repo with me? I could clone it then run a build and push it up to my own github.io page and see if I can find this issue

I think I have finally solved the styles not working in production issue thanks for @jmpolitzer example repo. A lot of CSS-in-JS packages (styled-components, emotion, etc) are now using speedy CSSOM insertRule for production builds. What happens is the innerText content is empty so this package would never work in production. I've made a change to extract the CSS correctly and you can test with the following beta:

npm install [email protected]

This beta version also has a rewrite using iframe's so that should also solve any issues with images not showing up.

Please me know the results. @jmpolitzer give it a shot I've just tested and it looks like your resume in fact prints out!

It works! Thanks for digging into this, @gregnb. As far as I'm concerned, this issue can be closed.

I will monitor the progress further if the positive feedback continues I will merge the beta into master

The alpha has been released along with a fix for canvas issues.

npm install [email protected] --save

I will soon look to close this thread as I believe the issue is now solved

Looks like this is no longer an issue. Closing

We are having a similar issue, using "react-to-print": "^2.5.0"
Print works great on local development, but on production styles are lost
Any suggestions here?

Hi @adam-ludgate, how are you loading the style in prod versus dev?

It's definitely some sort of loading issue. Doing this inside a Ruby on Rails project.
It looks like react-to-print cannot find the CSS styles defined in the webpacker directory, so I had to workaround this by moving the CSS outside into Rails.

I don't think this is necessarily a bug with react-to-print, more likely the way rails projects are configured. Anyway, noting the above workaround for anyone else who might encounter this using react-to-print with Rails.

Ok, thanks for the update. react-to-print should copy all styles (global, inline, and linked sheets) that are loaded on the page at the time printing is performed. It does not have the ability to load styles that are not already on the page.

Seems like 2.8.0 reintroduced the issue.

If I use <ReactToPrint /> component everything works fine, but with useReactToPrint hook (which is amazing btw) styles are not loaded.

Update: seems to be related to default props. If I pass copyStyles: true to the hook, styles are loading.

@SidKH interesting, thanks for reporting that. I wonder if the defaultProps from the class are not being properly used when in the hook, I'll take a look

@SidKH should be fixed in 2.9.0, thanks for the report

Hello! I'm still seeing this issue, only when performing a production build, in my app. I have tried the hook and the functional component, and explicitly set copyStyles to true in both instances, but I am still getting an error.

image

I suspect that this may have something to do with my homepage being set to './workloadReview/' in my package.json, so the link that is being generated in the href is not correct.

Further investigation showed that my application is in fact downloading the right css:
image

But when triggering ReactToPrint I can see the stylesheet it is attempting to use is invalid:
image
_Notice the doubling of "workloadReview" in the url_

Any suggestions on how to handle?

Edit: using "react-to-print": "^2.10.3",

For anyone else arriving here with the same issue I mentioned above, and you need a solution to this as soon as possible, like me..

I worked around this by using styled-components ( this was already installed in my application as a dependency for another library I use, react-select ) on the component that I was passing into the ReactToPrint component's content prop. This made the print menu have styles regardless of it's ability to load the rest of the application's styles.

I do still see ReactToPrint throwing errors to the console, so I'm still hoping for a workaround or some guidance from the devs.

Hi @Earle-Poole any chance you can make a working codesandbox or similar that I can use to debug?

Hey @MatthewHerbst, it looks like I'm not able to reproduce it in codesandbox, since the issue only occurs when the project gets built.

I then attempted to recreate the issue in a new CRA, using the same-ish code I'm using in production, but I was unable to reproduce the error. This is making me think even more that the issue we're seeing is a combination of the package.json "homepage" property being a relative path instead of static (i.e. "./workloadReview/"), the usage of CSS modules, and the way that this application and it's files are being hosted.

For some reason react-to-print is appending an additional "workloadReview" when it is performing it's copyStyles as the print window opens. This is just a guess, but I assume at the time of running the build scripts it is generating the minified CSS file which the application can find linked as "./static/css/file.css". When react-to-print is invoked, and it attempts to copy this element into the print window it is copying this link, but it is copying it as "./{homepage (in this case "workloadReview")}/static/css/file.css".

react-to-print does an exact copy of what exists in the DOM:

https://github.com/gregnb/react-to-print/blob/d6349a0c27e85887eddfe8b0f0e2832600b48869/src/index.tsx#L363-L378

So, the value with the double import already exists in your DOM. My guess is your import tool knows how to handle it because of the setup you have mentioned.

Can you possibly share more about the build and hosting setup of your application? This question might do better on StackOverflow possibly since my guess is you have some configuration you need to change there

Hi any fix for this problem? Im using electron with react-js (CRA). Works perfectly on development but still not reading the css file when built.
1

Using react-to-print: ^2.9.0

Update: used styled components and it works but still having error in console

@patrickJasonDuque does the file specified in that href actually exist at that location, or is it somewhere else? Can you share more about your build setup/process?

@MatthewHerbst Hi, thanks for your response. Yes it exist and It actually shows the the styles in the preview, for I am showing an editable preview which you can add contents. But when it is printed, it can't detect the styles

@patrickJasonDuque any chance you can replicate the issue in a codesandbox? I've been having a hard time debugging this since I don't know how to replicate it locally

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JoshuaKGoldberg picture JoshuaKGoldberg  路  3Comments

AJTJ picture AJTJ  路  4Comments

MikeSha picture MikeSha  路  4Comments

icebravo picture icebravo  路  5Comments

ishan7 picture ishan7  路  3Comments