PhantomJS does not recognize external CSS on the page

Currently, I have Phantom running on a Node server to generate pages from data and render them as PDFs.

Despite the pages rendering correctly as PDFs, I am facing an issue where the external CSS file is not being taken into account.

Below is a simplified version of my setup:

var phantom = require ('phantom');

phantom.create(function (ph) {
  ph.createPage(function (page) {
      var content = "";
      content += '<html><head>';
      content += '<link rel="stylesheet" href="/temp.css">'; 
      content += '<link rel="stylesheet" href="./temp.css">';
      content += '<link rel="stylesheet" href="temp.css">';
      content += '</head><body>';
      content += '<div class="myClass">I am supposed to be blue</div>';
      content += '</body></html>';
      page.set('content', content);

      setTimeout(function(){ 
          page.render("MyRenderedPDF.pdf", {format: 'pdf', quality: '100'}); 
      }, 1000)});
  }, {dnodeOpts: {weak: false}});

(I have included three different CSS references to ensure I am not missing the CSS due to a basic relative path syntax issue)

Here is the CSS content:

.myClass { color: blue; }

The PDF gets rendered in the same folder as my server, where the CSS is also located.

While everything else in the PDF displays correctly, the text specified in CSS is not appearing as blue as expected.

Although I could manually style the div, the CSS being used is extensive and I prefer accessing it directly.

Any suggestions on what might be causing this issue?

Answer №1

page.content = content (or page.set('content', content); in regular PhantomJS) is a way to directly update the content on the page. By doing this, the page is evaluated within the domain "about:blank". The resource "about:blank/temp.css" does not exist.

There are two main scenarios I see here.

Resource is accessible from the web

You can either provide the full URL from which to load the resource

content += '<link rel="stylesheet" href="http://example.com/path/temp.css">';
// OR
content += '<link rel="stylesheet" href="http://localhost/path/temp.css">';

or you can specify the domain using page.setContent(html, url):

page.setContent(content, "http://localhost/path/", function(){
    page.render("MyRenderedPDF.pdf", {format: 'pdf', quality: '100'}, function(){
        ph.exit();
    }); 
});

Remember to include callbacks, as the phantom module differs from plain PhantomJS scripts. Refer to Functional Details for more information.

Resource is a local file without a web server

In this case, you would need to use the fs module to read the file contents and include them as an embedded stylesheet.

content += '<style>' + fs.readFileSync("./temp.css") + '</style'; 

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

Making a column in a Vue data grid return as a clickable button

My goal is to utilize vue.js grid to display multiple columns with calculated text values, along with a clickable column at the end that triggers a dynamic action based on a parameter (such as calling an API in Laravel). However, when I include the last c ...

Convert coordinates from X and Y within a rotated ImageOverlay to latitude and longitude

After going over all the details in Projection's documentation and conducting various trial and error tests, I have hit a roadblock in finding a solution to this particular issue. All the solutions I have come across assume the x and y coordinates ar ...

Discover the underlying element that is being blurred when clicked

Is there a method to determine which element triggered the blur event when clicked outside? I want to update a ui-select value to match what the user typed in if they click outside of the dropdown. However, if they click on a dropdown item, I want to disc ...

What is the reason that the <script> tag cannot be directly inserted into the .html() method?

As I continue to learn front-end development, I've created my own version of JS Bin. When the 'run' button is clicked, a statement is executed to showcase the HTML, CSS, and JavaScript in an iframe (the output window): ("iframe").contents() ...

The render() method of the component is failing to execute even after the mobx store value has been updated

After successfully updating the store before fetching data from the server, everything seems to be working fine. However, once the data is fetched and the store is updated again, the render() method does not get called. Check out this code snippet @acti ...

Adapting to more user inputs in accordance with the feedback received from the AJAX response

Two user inputs are being received: area time Utilizing this information, the available restaurants in the specified area during that particular time are displayed. In addition, all the cuisines offered by these restaurants are displayed as checkboxes. ...

What are the steps for integrating a date and time picker bootstrap plugin?

Referencing a tutorial from http://www.w3schools.com/bootstrap/bootstrap_modal.asp: <button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">Open Modal</button> <div id="myModal" class="modal fade" role= ...

Looping through jQuery, I am adding divs, but frustratingly I can only insert text into the initial div created. Why

var numPills = 3 for(var i=0; i< numPills; i++){ //var currentPill = JUser.pill1.; $(".col-r-in").append( $('<div/>') .attr("id", "medsProgress") .addClass("roundedBar") ); $('#medsProgress').append( $('<div/>&apo ...

Sending parameters in GraphQL with Typescript results in an empty set of curly braces being returned

I am new to learning GraphQL with Typescript and I am trying to pass an argument in a GraphQL function to return something dynamically. I have been struggling with this issue for the past hour and could not find any solutions. Here are the relevant code sn ...

Using a `right: 0` value will not be effective when using absolute positioning

Currently, I am in the process of developing a website utilizing Bootstrap 3.3.6. After going through a tutorial on how to create a responsive banner slider, I found this resource helpful: http://www.jqueryscript.net/slider/Full-Width-Responsive-Carousel- ...

Webpack in Vuejs does not have access to the keys defined in dev.env.js file

The framework utilized here is vuejs-webpack, with build and config files located here. No modifications have been made to these files. According to the information on Environment Variables, the keys specified in dev.env.js should be accessible during the ...

Error: The function .default.auth.signout is not recognized in the REACT and Firebase environment

I've come across several error questions on StackOverflow, but most remain unanswered. The ones that are answered don't seem to solve my issue. I need help debugging this particular error. In my REACT project using Firebase, I'm working on ...

I'm perplexed by the inner workings of infinite ajax scroll in fetching additional posts

As someone who is new to JavaScript, I find it challenging to grasp the concept, especially when incorporating it with HTML. Despite this, I decided to experiment with infinite ajax scroll functionality. Below is my code snippet: var ias = jQuery.ias({ ...

How can I retrieve a global variable in Angular that was initialized within an IIFE?

I'm a beginner in Angular, so I ask for your patience. Currently, I am in the process of migrating an app from Asp.net MVC5 to Angular. One of the key functionalities of this application involves connecting to a third-party system by downloading a Jav ...

Dynamic updating in a React application with an express server

Currently, I have set up a boilerplate for a MERN application with an express server on the backend and react on the frontend. My goal is to implement hot reloading in my app so that changes in the react code can be reflected without needing to refresh the ...

A guide to using select2.js to activate a selection based on a data attribute

I'm faced with the following html snippet: <div class='multiWrapper'> <select id="multi" class="js-dropdown-from-code"> <optgroup class='def-cursor' label='Code' data-city ...

Position the typography component to the right side

Is there a way to align two typography components on the same line, with one aligned to the left and the other to the right? I'm currently using this code but the components are aligned next to each other on the left side. const customStyles = makeSt ...

Utilizing Selenium Webdriver to efficiently scroll through a webpage with AJAX-loaded content

I am currently utilizing Selenium Webdriver to extract content from a webpage. The challenge I'm facing is that the page dynamically loads more content using AJAX as the user scrolls down. While I can programmatically scroll down using JavaScript, I a ...

Tips for implementing a checkbox (with tick/untick functionality) as a replacement for a plus/minus toggle using HTML

Is it possible to use checkboxes instead of plus and minus signs for expanding and collapsing sections? Can the plus and minus symbols be incorporated into the checkbox itself, so that clicking on the checkbox toggles between plus and minus states? Any hel ...

Utilizing AJAX for showcasing the data from an XML document

Our professor gave a brief explanation of AJAX, expecting us to showcase the data from an XML file in a scrollable text area on our website. Unfortunately, I am facing issues with loading the XML file into the designated div area. Any assistance or suggest ...