Stencil custom page javascript not firing - javascript

I'm trying to create a custom web page in stencil website and trying to add custom javascript module.
This is the html file named '/templates/pages/custom/page/customz.html'
{{~inject 'template' template}}
<h2>Hello World!</h2>
<body>
Some custom content!
<body>
<script>window.__webpack_public_path__ = "{{cdn 'assets/dist/'}}";</script>
<script src="{{cdn 'assets/dist/theme-bundle.main.js'}}"></script>
<script>window.stencilBootstrap("{{page_type}}", {{jsContext}}).load();</script>
This is the javascript file named '/asset/js/theme/customz.js'
import PageManager from './page-manager';
export default class Customz extends PageManager {
onReady() {
console.log('onReady');
}
constructor(context) {
super(context);
console.log(context);
}
}
then i added this in app.js file
const customClasses = {
'pages/custom/page/customz': () => import('./theme/customz')
};
and also added it .stencil file to test it locally
I also created the web page in bigcommerce dashboard.
The problem i have is that the HTML is loaded but the Javascript file is not injected (i cannot see the console log strings in console or other js logic i insert).
Where can be the problem?

The place I usually start when troubleshooting a custom template is the related section on the BigCommerce Dev Center here: https://developer.bigcommerce.com/stencil-docs/storefront-customization/custom-templates#troubleshooting-template-authoring
If you've verified the version of the Stencil CLI and URL you're using, try using this same code with the base Cornerstone theme on the latest version.

you need add link for Windows too:
Look like:
const customClasses = {
'pages/custom/page/customz': () => import('./theme/customz'),
'pages\\custom\\page\\customz': () => import('./theme/customz')
};
And your custom page must contains:
`{{~inject 'template' template}}
<script>window.__webpack_public_path__ = "{{cdn 'assets/dist/'}}";</script>
<script src="{{cdn 'assets/dist/theme-bundle.main.js'}}"></script>
<script>window.stencilBootstrap("{{page_type}}", {{jsContext}}).load();</script>`
If don`t connection on base file from layout.

Related

How to fetch files from CDN with NuxtJS content module?

I want to fetch files from another server (e.g. a CDN) with the #nuxtjs/content module so that the .md files can be managed independently without Nuxt.js.
My current nuxt.config.js file looks like this:
export default {
...
content: {
dir: 'http://some-cdn.xyz/content/'
},
...
}
Now I want to load the content in the pages/_slug.vue file:
<template>
<div>
<NuxtContent :document="doc" />
</div>
</template>
<script>
export default {
async asyncData({ $content, params }) {
const doc = await $content(params.slug || 'index').fetch();
return { doc };
},
};
</script>
Now when I type in http://localhost:3000/some-page, I should get the corresponding file (some-page.md) from the CDN. Instead, I get this error from Nuxt.js: /some-page not found.
What should I do to get it working and is this even possible with my current setup?
As told here: https://github.com/nuxt/content/issues/237
This is not doable with the content module and is not planned to be done neither. A solution would be to manually fetch the files during the build time or alike.
You can maybe get some inspiration from this comment: https://github.com/nuxt/content/issues/37#issuecomment-664331854 or use another markdown parser.
Since #nuxtjs/content can't fetch files from another server, I used the marked.js library instead.

How to create vanilla javascript widgets as web components and import into a page dynamically?

I am working on a web application which can host mini-apps (or modules) developed in vanilla Js, HTML, CSS.
The host application dynamically loads (using fetch API) the mini-apps (or modules) into its pages and then I want these mini-apps to independently request for their data or do whatever they want to. I want these mini-apps isolated from the host scripts and styling but the host should be able to execute functions of these mini-apps (or modules).
Example: The dashboard of Microsoft Azure portal. It has widgets which can be selected, customised and placed by the user, and after loading of the host dashboard these widgets independently fetch for their data. Also, the period and auto-refresh time can be controlled by the host application.
Priorities:
• Modules should be able to execute their own JS scripts.
• If possible then everything should be in vanilla js (or Stenciljs / Vue.js)
Current File Structure:
main.html
js (dir)
style (dir)
modules (dir)
• module-one
| module.html
| module.css
| module.js
• module-n
...
I have tried creating custom HTML element and then appending HTML and CSS of module to shadowDom. But I still don't know how to get its JS working. If I insert module.js dynamically to main.html then somehow I need to change roots of all module.js appended in host application from
document to shadowRoot
Example:
//module.js
const sayHelloBtn = document.getElementById('sayHello');
sayHelloBtn.addEventListener('click', () => {console.log('Hello')});
//module.js after appending to host (main.html)
const mod = document.querySelector('module-one').shadowRoot;
const sayHelloBtn = mod.getElementById('sayHello');
sayHelloBtn.addEventListener('click', () => {console.log('Hello')});
Please let me know if further elaboration or clarification on question is required. Thank You :)
Problem Update:
I get a json of all the modules from an API and dynamically create custom elements with shadow root . I fetch the module files using the fetch API and then append them to the custom elements. I am able to successfully append the .html and .css to respective custom elements but cannot run JS inside shadow DOM. If I dynamically import the JS globally to the main.html then some how I need the JS to access the elements in its shadowRoot and also the functions should not conflict with other module's js functions with same name.
I have tried creating classes in each module.js which holds its respective methods, variable and a init() which does all the module's initialisation.
//module.js
class ModuleAbc {
constructor(host = document) { // shadowRoot is passed when instantiating from the host application
this.docRoot = host;
console.log('docRoot set: ', this.docRoot);
}
init() {
console.log('initialising module at host: ', this.docRoot);
const docRoot = this.docRoot;
const btn = docRoot.getElementById('cm'); //this element is inside shadowRoot
btn.addEventListener('click', () => {
console.log('Hello from mod 1!');
});
}
}
Now I do not know how to call init() of all the classes because their names are different for every module.
//HOST JS (main.js)
let mod_name = 'ModuleAbc';
const mod = new mod_name(module_root); //THIS DOESN'T WORK
mod.init();
Problem is resolved using Estus Flask's suggested solution

reactjs project load javascript libraries and attach to window object

I would like to add some javascript libraries to my reactJS project.
I do this by adding script tags to the section of index.html
<script src="../src/components/reports/scripts/stimulsoft.reports.js"></script>
<script src="../src/components/reports/scripts/stimulsoft.viewer.js"></script>
and usage of library is like:
class Viewer extends React.Component {
render() {
return <div id="viewerContent"></div>;
}
componentWillMount() {
var report = Stimulsoft.Report.StiReport.createNewReport();
report.loadFile("reports/Report.mrt");
var options = new Stimulsoft.Viewer.StiViewerOptions();
this.viewer = new Stimulsoft.Viewer.StiViewer(options, "StiViewer", false);
this.viewer.report = report;
}
componentDidMount() {
this.viewer.renderHtml("viewerContent");
}
}
but I have this error:
these are original sample Stimulsoft Reports.JS and GitHub
Based on comments under the question, and the guides presented in index.html file of react project as follows:
//Notice the use of %PUBLIC_URL% in the tags above.
//It will be replaced with the URL of the `public` folder during the build.
//Only files inside the `public` folder can be referenced from the HTML.
I placed scripts folder into the public folder of react project and edit src attribute to new source address, and my problem was solved
and this code work for me:
<script src="%PUBLIC_URL%/StimulSoft/scripts/stimulsoft.reports.js"></script>
<script src="%PUBLIC_URL%/StimulSoft/scripts/stimulsoft.viewer.js"></script>

How to run a specific jquery script after each page load?

My client sent me an HTML template that heavily relies on jQuery. The app itself runs on nuxt. I have a js file that contains a whole lot of $(function(){...}). Now I don't know how to run this file on each page transition.
So far, I have tried:
Creating a plugin inside plugins dir that looks like:
export default async ({ app }) => {
app.router.afterEach((to, from) => {
require('~/static/js/base-init.js');
})
}
here base-init.js has all those jquery code
Adding mounted (inside default.vue layout) but that doesn't work either.
Does anyone have a clue?
If you want to use your jquery file on nuxt just do this
Inside your nuxt.config.js add
npm i jquery
plugins: [
'~plugins/my-jquery-code.js'
]
And inside plugins/my-jquery-code.js
if (process.BROWSER_BUILD) {
const $ = require('jquery')
$(function() {
console.log('document ready!');
// do whatever you want with html and jquery
})
}
I'm refering to this link => https://github.com/nuxt/nuxt.js/issues/356
its work for me !
Good Lucks.

Importing tracking.js into an angular project

I have downloaded tracking.js and added it to my /src/assets folder
In my angular-cli.json file I have added to my scripts:
"scripts": [
"../src/assets/tracking/build/tracking-min.js"
],
issue here - In my angular component, I import tracking as follows:
import tracking from 'tracking';
and in the chrome inspection window I can hover over 'tracking' and see all of the properties as shown:
I can even call the ColorImage constructor in the console window! :
However when it tries to execute the constructor in my code I get the error about tracking being undefined:
I had assumed it was because I wasn't passing in the tracking object through the constructor in the traditional DI fashion, but when doing so I got the error that the namespace couldn't be used as a type:
The only other thing I could think of was to try and add the external reference in the main index.html file, but I got an error about strict MIME checking.
To clarify: this is all happening in my angular component constructor (when the tracking methods get exercised)
Any ideas?
go to your node_modules folder and find this file : "node_modules/tracking/build/tracking.js" . open the file and add this line of code to end of the file :
module.exports = window.tracking
save file and in use this code to import it :
import * as tracking from 'tracking';
I don't think you can use DI with that external library. However, you should be able to create a new instance in the constructor:
import tracking from 'tracking';
constructor(...) {
this.colors = new tracking.ColorTracker(...);
}
myFunction() {
this.colors.doWhateverIWant();
}
If you only want a single tracking instance throughout your app, then you'll have to create your own trackingService and inject that.
another solution is to reference the tracking.js via script tag :
<html>
<head></head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tracking.js/1.1.3/tracking-
min.js"></script>
</body>
</html>
and in your component.ts write :
(window as any).tracking.ColorTracker(["magenta"]);

Categories