Custom route in plugin drops 404 error on not defined client script

Solved Plugin Development
  • Hello! I set up a custom route via own plugin:

    plugin.init = async function (params, callback) {
    
    	var router = params.router;
    	var middleware = params.middleware;
    
    	// Define the function that renders the custom route.
    	function render(req, res, next) {
    
    		// Get whatever data you want to send to the template here.
    		let data = {};
    		// This is the path to your template without the .tpl, relative to the templates directory in plugin.json
    		var template = 'testinger'
    
    
    		// GET the requested URL
    		var requestedURL = req.originalUrl;
    
    		if(!req.uid){
    			// ITS A GUEST
    			data.debug = "Guest";
    			data.reqedURL = requestedURL;
    			req.session.returnTo = requestedURL;
    			return res.redirect('/login');
    			//
    		}else{
    			// ITS A REGISTERED
    			data.debug = "LOGGED IN!";
    			data.reqedURL = requestedURL;
    
    			// Send the page to the user.
    			res.render(template, data);
    		}
    		
    	}
    
    
    	// This actually creates the routes, you need two routes for every page.
    	// The first parameter is the actual path to your page.
    	params.router.get('/discord/topic', params.middleware.buildHeader, render);
    
    };
    

    It works when I access the url directly.

    Bildschirmfoto 2021-03-23 um 20.34.32.png

    But if I use a forum internal link to get to the page it drops an error:

    Bildschirmfoto 2021-03-23 um 20.34.41.png

    Also logout button isn't working in both situations.

    client console prints following:

    Bildschirmfoto 2021-03-23 um 20.35.20.png

    Server console log is ok and there are no errors.

    What do i wrong?


    €:

    But if I use a forum internal link to get to the page it drops an error:

    This is fixed by define /api/ route too:

    params.router.get('/api/discord/topic', render);
    

    And Logout-Button is still not working... 😕 but only in my custom route... everything is working fine elsewhere

    Logout-Button fixed
    I now use:

    routeHelpers.setupPageRoute(router, '/discord/topic/', middleware, [(req, res, next) => {
    		winston.info(`[plugins/discord-topic] In middleware. This argument can be either a single middleware or an array of middlewares`);
    		setImmediate(next);
    	}], (req, res) => {
    		winston.info(`[plugins/discord-topic] Navigated to ${nconf.get('relative_path')}/discord-topic`);
    		render(req, res);	// replace this with res.render('templateName');
    	});
    

    instead of:
    params.router.get('/discord/topic', params.middleware.buildHeader, render);


    But why is it looking for a source I didn't defined?
    Failed to load resource: the server responded with a status of 404 ()
    GET https://nodebb.development.fail/assets/src/client/testinger.js?v=9ono28m56s4 net::ERR_ABORTED 404

    Everything seems to be working but why is this last error appearing?

  • Yeah module path get confusing fast. Did you try putting testinger.js in "scripts" like this.

    // plugin.json

    "scripts": [
      "static/lib/testinger.js"
    ]
    

    testinger.js

    define('forum/testinger', function () {
      var module = {};
      module.init = function () {};
      return module;
    });
    

    Let me know if that works.

  • When you render a template with res.render('templateName', data); the client side will try to load the javascript for that page using the templateName and if it doesn't exist it will 404. The logic for this is in here.

  • @baris Thank you for your reply 🙂

    changed

    "scripts": [
       "static/lib/main.js"
    ],
    

    to

    "scripts": [
       "static/lib/testinger.js"
    ],
    

    and renamed
    myplugin/static/lib/main.js
    to
    myplugin/static/lib/testinger.js

    I also tried both at the same time.

    Still got the same error...?

    GET https://nodebb.development.fail/assets/src/client/testinger.js?v=q8nigrofm7g net::ERR_ABORTED 404


    I ran ./nodebb build & grunt no affect here. Do I miss anything else?


    If I use following in testinger.js

    $(window).on('action:ajaxify.end', function(data) {
    
    	console.log("ENDED AJAX BOT!");
    
    });	
    

    It console.logs the defined ENDED AJAX BOT.
    So everything seems to be fine except the error.

  • Test it with modules

    "modules": {
    	"testinger.js": "./static/lib/testinger.js"
    }
    

    Then ajaxify should be able to require and load that file.

  • @dogs said in Custom route in plugin drops 404 error on not defined client script:

    $(window).on('action:ajaxify.end', function(data) {

    console.log("ENDED AJAX BOT!");

    });

    You need to make testinger.js a AMD module with an init method:

    define('testinger', function () {
      var module = {};
      module.init = function () {};
      return module;
    });
    
  • @baris Testest nearly every possible combo. Don't get the error fixed.

  • @baris said in Custom route in plugin drops 404 error on not defined client script:

    define('testinger', function () {
    var module = {};
    module.init = function () {};
    return module;
    });

    Yeah maybe it was

    define('forum/testinger', function () {
      var module = {};
      module.init = function () {};
      return module;
    });
    
  • @baris Nothing of that works for me. 😕

    Is it up to me or why do I have to define a script I dont need it?
    I already have client.js in my plugin - which works - so why do I must add a Script I do not actually need?


    So I tried everything. Still get the same error... 😞 Thank you for your time!

  • It's just the way nodebb works with. Right now if you render a template with res.render the client side will automatically try to load a client side javascript file with the same name.

    Does it work if you try this.

    plugin.json

    "modules": {
      "forum/testinger.js": "./static/lib/testinger.js"
    }
    

    testinger.js

    define('forum/testinger', function () {
      var module = {};
      module.init = function () {};
      return module;
    });
    

    When you build nodebb you should see testinger.js in build/public

  • @baris Seems to work.
    nodebb.development.fail/build/public

    .
    ├── acp.min.js
    ├── acp.min.js.map
    ├── admin.css
    ├── client.css
    ├── language
    ├── nodebb.min.js
    ├── nodebb.min.js.map
    ├── plugins
    ├── rjs-bundle-admin.js
    ├── rjs-bundle-client.js
    ├── src
    └── templates
    

    nodebb.development.fail/nodebb.development.fail/build/public/src/modules

    .
    ├── ace -> ../../../../node_modules/ace-builds/src-min
    ├── Chart.js -> ../../../../node_modules/chart.js/dist/Chart.min.js
    ├── clipboard.js -> ../../../../node_modules/clipboard/dist/clipboard.min.js
    ├── compare-versions.js -> ../../../../node_modules/compare-versions/index.js
    ├── composer
    ├── composer.js -> ../../../../node_modules/nodebb-plugin-composer-default/static/lib/composer.js
    ├── cropper.js -> ../../../../node_modules/cropperjs/dist/cropper.min.js
    ├── emoji-dialog.js -> ../../../../node_modules/nodebb-plugin-emoji/build/public/lib/emoji-dialog.js
    ├── emoji.js -> ../../../../node_modules/nodebb-plugin-emoji/build/public/lib/emoji.js
    ├── forum
    ├── highlight.js -> ../../../../node_modules/nodebb-plugin-markdown/public/js/highlight.js
    ├── highlightjs-line-numbers.js -> ../../../../node_modules/nodebb-plugin-markdown/public/js/highlightjs-line-numbers.js
    ├── jquery-form.js -> ../../../../node_modules/jquery-form/dist/jquery.form.min.js
    ├── jquery-ui -> ../../../../node_modules/jquery-ui/ui
    ├── mousetrap.js -> ../../../../node_modules/mousetrap/mousetrap.min.js
    ├── pulling.js -> ../../../../node_modules/pulling/build/pulling-drawer.js
    ├── slideout.js -> ../../../../node_modules/slideout/dist/slideout.min.js
    ├── swiper.js -> ../../../../node_modules/nodebb-theme-2/node_modules/swiper/swiper-bundle.min.js
    ├── timeago
    ├── tinycon.js -> ../../../../node_modules/tinycon/tinycon.js
    ├── xregexp.js -> ../../../../node_modules/xregexp/xregexp-all.js
    └── zxcvbn.js -> ../../../../node_modules/zxcvbn/dist/zxcvbn.js
    
    dogs@scp:/home/users/dogs/www/nodebb.development.fail/nodebb.development.fail/build/public/src/modules/forum$ tree
    .
    └── testinger.js -> ../../../../../node_modules/nodebb-plugin-discord-bot/static/lib/testinger.js
    

    Btw.: It doesn't matter that the template is named differently than the route, does it?

  • Yeah module path get confusing fast. Did you try putting testinger.js in "scripts" like this.

    // plugin.json

    "scripts": [
      "static/lib/testinger.js"
    ]
    

    testinger.js

    define('forum/testinger', function () {
      var module = {};
      module.init = function () {};
      return module;
    });
    

    Let me know if that works.

  • @baris said in Custom route in plugin drops 404 error on not defined client script:

    define('forum/testinger', function () {
    var module = {};
    module.init = function () {};
    return module;
    });

    I'am sorry I edited my last post. It was display in /forum I was looking for testinger.js in ./.

    This worked! You are awesome! The error is gone! 🙂 Thank you very much 🙂

  • No worries, the difference with "scripts" is that the file gets bundled with nodebb.min.js so it will be loaded even if that page isn't visited. If you put it in modules it only gets downloaded when the user visits that page.

    You can get "modules" working, just need to figure out the correct path. It might be

      "modules": {
            "../client/testinger.js": "./static/lib/testinger.js"
       },
    

    So it is placed at the correct place in the build folder.

  • @baris said in Custom route in plugin drops 404 error on not defined client script:

    "modules": {
    "../client/testinger.js": "./static/lib/testinger.js"
    },

    Yeah that worked too! Its to saw both variants! Thank you 🙂

  • @baris I think may I found a bug.

    You said:

    If you put it in modules it only gets downloaded when the user visits that page.

    Let's say my module contains following code:

    define('forum/testinger', function () {
    	var module = {};
    	module.init = function () {};
    	return module;
    });
    
    'use strict';
    
    $(document).ready(function () {
    
    });
    
    $(window).on('action:ajaxify.end', function(data) {
    	console.log("just trigger on defined new route")
    });	
    

    I can surf however I want, the code won't be executed. As soon as I go on my new route, the script loads and the console outputs. So far so good. 👍 Works as expected 🙂

    But after I was once on the page, the script loads again and again on all other pages.

    I'm not sure ... you said:

    it only gets downloaded when the user visits that page

    I assumed that it would still not work on other sites afterwards. But the way it looks: once loaded, it persists and runs still on all pages.

    I just wanted to make sure that this is normal? And if so, then I see no right to exist for the module. Then a simple script is enough?

  • It is normal. See my comments below.

    define('forum/testinger', function () {
    	var module = {};
    	module.init = function () {
               console.log('will be logged everytime /testinger page is loaded');
            };
    	return module;
    });
    
    'use strict';
    
    $(document).ready(function () {
        console.log('will be logged once when /testinger is navigated to');
    });
    
    $(window).on('action:ajaxify.end', function(data) {
    	console.log("will be logged everytime a page navigation happens after loading /testinger");
    });
    
  • @baris said in Custom route in plugin drops 404 error on not defined client script:

    console.log('will be logged everytime /testinger page is loaded');

    Okay thank you and I'm sorry 🙉 , these are probably basic javascript programming things. But I'm a beginner and I'm doing my best here....

    One last question, is it then also possible to use the hooks inside the AMD module? Like:

    $(window).on('action:composer.submit', function(ev, data) {
       //
    })
    
    $(window).on('action:ajaxify.end', function(data) {
    	console.log("will be logged everytime a page navigation happens after loading /testinger");
    });
    
    // ...
    
  • Yes you can use them inside the AMD module but keep in mind once you add an event listener on the window object it will be called everytime there is an action:ajaxify.end. If you don't want it triggered after you leave that page you need to turn it off with $(window).off('eventName', myMethod)


Suggested Topics


  • Cached scripts

    Plugin Development
    1
    1 Votes
    1 Posts
    230 Views

    Hi all!
    I've run into an issue that when I deploy a new version of my theme/plugin, most users don't get any changes done until they do a hard refresh. This only seems to affect the client side Javascript, so everything looks updated, but in reality functionality gets lost.

    Has anyone stumbled upon something similar? Is there a better way to release code?

    The background in this is that I have forked Persona and built upon it, so all changes to the platform is basically in the theme. Is there a way to make sure all clients receive all updates?

    Thanks!

  • 0 Votes
    3 Posts
    572 Views

    @PitaJ I see. Tks for the update. Do you have this in your roadmap?

  • 0 Votes
    2 Posts
    2k Views

    Went ahead and made the changes already 😆

  • 0 Votes
    5 Posts
    4k Views

    Hi all,

    I realize this is an old topic, but given that I'm dealing with exactly the same problem, I figured it would be sensible to reply here. Essentially, I've followed the advice of @pichalite and created a simple IIS forward proxy for my NodeBB server. Unfortunately this solution does not yield the desired result, as many requests for resources are not being made to the correct directory - instead, requests are being made to the root level of the IIS Web server (e.g., GET http//website.ca/stylesheet.css?4210ebb0-9225-4237-b2ad-87d88b61756b), and not to the specified port where NodeBB is being hosted (e.g., http://website.ca:4567 or http://localhost:4567).

    Any ideas? I've played around with reverse proxies and outbound rules to route all outgoing traffic from http://localhost:4567 to the same URL I've specified for the proxy rule (e.g., http//website.ca/associates-hub) to no avail... If more info or screenshots are needed, they can be provided. I've been banging my head against the wall trying to cycle through all possible solutions to this problem. Any insight would be GREATLY appreciated.

    Thanks,

    Cam

  • 0 Votes
    2 Posts
    2k Views

    @inhuman We could build one out for you, possibly 😄 Reach out to us at [email protected]