@tsteur opened this Issue on September 21st 2018 Member

We would start with one CDN, for example AWS CloudFront, but have an API to easily add more through plugins or core directly.

Plugins also need to be able to sync their own files to the CDN, for example the tag manager:
refs https://github.com/matomo-org/tag-manager/issues/81#issuecomment-423368044

@tsteur commented on October 1st 2018 Member

I presume many/most CDNs don't need to upload a file to the CDN but they fetch it automatically. Possibly more interesting be a feature to invalidate the cache on a CDN.

@SARAVANA1501 commented on June 11th 2020

@tsteur For tag-manager I understood, there is a change event, what about whole matomo core? What are all the files should be hosted in CDN, Thought of contributing to matomo level. If you provide some information about matomo core, that would be great for me to start.

@tsteur commented on June 11th 2020 Member

You can use the very same logic for the JS tracker by also listening to this event:

'CustomPiwikJs.piwikJsChanged' => array('function' => 'onStaticFileChanged', 'after' => true),
@tsteur commented on June 11th 2020 Member

This be actually perfect for a new plugin if you wanted to share the code and could be put on the Matomo Marketplace see https://developer.matomo.org/guides/distributing-your-plugin

@SARAVANA1501 commented on June 12th 2020

Cool. I will create initial version of plugin with AWS s3 support, Lets leverage further from there.

@SARAVANA1501 commented on June 15th 2020

@tsteur Created initial draft of plugin... I will publish this to marketplace ASAP.

@SARAVANA1501 commented on June 15th 2020
@tsteur commented on June 15th 2020 Member

Awesome πŸ‘ well done

@SARAVANA1501 commented on June 16th 2020

@tsteur Can we officially close this thread?

@tsteur commented on June 16th 2020 Member

@SARAVANA1501 maybe one more thing... I reckon it be good if the install instructions could directly show the correct CDN URL if a CDN endpoint / path is configured. This could work like this:

Listen to these events:

            'API.TagManager.getContainerEmbedCode.end' => 'onGetTagManagerCode',
            'API.TagManager.getContainerInstallInstructions.end' => 'onGetTagManagerCode',

Then rewrite the path like this:

    public function onGetTagManagerCode(&$returnedValue, $extraInfo)
      if (self::getCdnUrl()) { // if user has a CDN url configured
            $piwikBase = $this->getBaseUrl();
            $containerJs = $piwikBase . '/' . trim(Piwik\Container\StaticContainer::get('TagManagerContainerWebDir'), '/') .'/';
            if (is_string($returnedValue)) {
                $returnedValue = str_replace($containerJs, self::getCdnUrl() . '/', $returnedValue);
            } elseif (is_array($returnedValue)) {
                foreach ($returnedValue as &$val) {
                    if (!empty($val['embedCode'])) {
                        $val['embedCode'] = str_replace($containerJs, self::getCdnUrl() . '/', $val['embedCode']);
            $returnedValue = str_replace($containerJs, self::getCdnUrl() . '/', $returnedValue);

    private function getBaseUrl()
        $piwikBase = str_replace(array('http://', 'https://'), '', Piwik\SettingsPiwik::getPiwikUrl());
        return rtrim($piwikBase, '/');

    private static function getCdnUrl($includeProtocol = false)
if (!$includeProtocol) {
        return 'mycdn.mydomain.com/mypath'; // path should be read from a config
        return 'https://mycdn.mydomain.com/mypath'; // path should be read from a config

Not sure it's clear but it would basically replace any path like https://matomo.example.com/js/container_349449.js and turn it into https:://cdn.example.com/mypath/foo/container_349449.js.

@SARAVANA1501 commented on June 20th 2020

'API.TagManager.getContainerEmbedCode.end' => 'onGetTagManagerCode',
'API.TagManager.getContainerInstallInstructions.end' => 'onGetTagManagerCode', Method is invoked but i am receiving params as empty. It is not working as expected. Where i can documentation for all these events?

@tsteur commented on June 20th 2020 Member

@SARAVANA1501 there is only this documentation about it: https://developer.matomo.org/3.x/api-reference/events#apipluginnamemethodnameend

We're using it ourselves though as well and it works for us.
It should be invoked when you view install instructions etc

@plastikschnitzer commented on June 21st 2020

Do you also plan to include other cdn?

@SARAVANA1501 commented on June 22nd 2020

@plastikschnitzer Add you CDN specification here. If possible, feel free to contribute.

@SARAVANA1501 commented on June 25th 2020

@tsteur I am getting empty params, Have a look at the code : https://github.com/SARAVANA1501/plugin-TrackerJsCdnSync/blob/14441664bc1d5063bab70c9005a67ea0a456f320/TrackerJsCdnSync.php#L42

Function invoked but params not passed. Tried of trying various options, I can’t find the route case.

@tsteur commented on June 25th 2020 Member


maybe try

     fwrite($myfile, var_export($returnedValue, 1));
        fwrite($myfile, var_export($extraInfo, 1));
@SARAVANA1501 commented on June 26th 2020
        $myfile = fopen("newfile.txt", "w") or die("Unable to open file!");
        fwrite($myfile, var_export($returnedValue, 1));
        fwrite($myfile, var_export(array(array("description" => "fgs", "embedCode" => "Sdfsdf")),1));
        $returnedValue = array(array("description" => "fgs", "embedCode" => "Sdfsdf"));

Getting params now, But returning corrected value is not working. I tried above code (line number 4 and 5) not working.

@tsteur commented on June 28th 2020 Member

Try removing this line maybe and see if it works? $returnedValue = array(array("description" => "fgs", "embedCode" => "Sdfsdf"));

I don't think you can simply overwrite $returnedValue[0] but should probably use a logic like in https://github.com/matomo-org/matomo/issues/13462#issuecomment-644993731

@SARAVANA1501 commented on June 28th 2020

https://github.com/matomo-org/matomo/issues/13462#issuecomment-644993731 this is not at all working, Feel free contribute a rough solution as a PR, I will refactor and write proper test case for that.

@tsteur commented on June 28th 2020 Member

@SARAVANA1501 we're using the above code ourselves and it works nicely for us. Unfortunately I don't really have time to create this PR. Adding those events and the methods should replace the shown path to the JS when you go to the TagManager and then view install instructions.

@SARAVANA1501 commented on July 1st 2020

@tsteur Working perfectly man, I have some other plugin which is blocking some action. i will publish soon. thanks.

@tsteur commented on July 1st 2020 Member

Awesome, thanks!

@SARAVANA1501 commented on October 15th 2020

@tsteur You know, we have plugin to save the container file in CDN, But how to sync piwik.js tracker file to CDN?

@SARAVANA1501 commented on October 15th 2020

I know we have to configure CustomPiwikJs.piwikJsChanged' => array('function' => 'onStaticFileChanged', 'after' => true), to sync the file after update, what about initial or first time load?

@tsteur commented on October 15th 2020 Member

Yes exactly that's how you would do it πŸ‘

BTW In Matomo 4 it would become 'CustomJsTracker.trackerJsChanged' => array('function' => 'onStaticFileChanged', 'after' => true),

This Issue was closed on July 1st 2020
Powered by GitHub Issue Mirror