Answers.Body: <p>That's the dream, isn't it? CDN everywhere, no database hits, etc. How "static" is your site? Unlike other CMS, the great thing about Craft is that you can store information everywhere and pull it out anywhere. That gets to be dynamic content problem nightmare unless you're very diligent about knowing what will happen, for example:  "updating this page will also update content on the home page, the blog index, related white papers section, author archives, etc".  </p>
  
  <p>Let' say you update the title of one of your main areas that's also part of your navigation: <code>Services</code> becomes <code>Products</code> for example. Now you have to invalidate every single page. </p>
  
  <p>So it can get complex quickly but if you have a very simple site, obviously, the above doesn't apply. </p>
  
  <p>One way to pull this off would be to create a subdomain, like <code>admin.whatever.com</code>. Your admins would login to this URL. As far as Craft is concerned, it'll serve up on whatever domain you need, you just need multiple environment <a href="https://craftcms.com/docs/multi-environment-configs" rel="nofollow noreferrer"><code>config.php</code></a> and template trickery. </p>
  
  <p>In your template files, check for the server name. </p>
  
  <pre><code>{% if craft.request.serverName is not "domain.com" %} {% reqireLogin %} {% endif %}
  </code></pre>
  
  <p>This will prevent non-logged in users from trying to accesses the admin pages, otherwise Craft will serve up your non-CDN on that domain to anyone who hits it (which is not something you want to have happen generally).</p>
  
  <p>Unlike something like WordPress where it actually stores URLs in the database, Craft uses reference tags and builds up the URL on the fly so you generally don't have to worry about relative vs absolute URLs.</p>
  
  <p>The hardest part of this is going to be the cache invalidation. Unlike static files, where you can just upload a new file with a different filename on the CDN to invalidate them, pages are much different. To make matters worse, it can <a href="http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html#InvalidationLimits" rel="nofollow noreferrer">take up to 10-15 minutes</a> for that invalidation to happen on Cloudfront. </p>
  
  <p>I use nginx here for static/microcaching and it works pretty well but the idea is the same. I can share some code I use to invalidate its cache but basically you want to create a plugin that listens on <code>entries.SaveEntry</code> and then tell CloudFront to invalidate the cache after it's saved. Something like:</p>
  
  <pre><code>public function init()
  {
  
      parent::init();
      craft()-&gt;on('entries.saveEntry', function (Event $event) {
  
          $entry = $event-&gt;params['entry'];
  
          if ($entry-&gt;url &amp;&amp; $entry-&gt;enabled) {            
  
          $url = $entry-&gt;url;
  
              try {
  
                   // do CloudFront stuff here
                  if (!$response-&gt;isSuccessful()) {
                      return;
                  }               
  
  
  
  
              } catch (Exception $e) {
                  // something happened.                  
              }
  
          }
      });
  }
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-02-08T19:30:09.953Z
Answers.Text: Thanks for the comprehensive answer. I am wondering how the 'multiple environment config.php and template trickery' might look like
Answers.UserDisplayName: Sven
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-02-02T23:38:08.473Z
Answers.LastActivityDate: 2017-02-02T23:38:08.473Z
Answers.UserDisplayName: RitterKnight
Body: <p>I have a fully static website. All images and videos are currently delivered via aws cloudfront. </p>
  
  <p>Now I am thinking of delivering the HTML via cloudfront as well. My concern is that craftCMS routing will always point to the CDN domain. </p>
  
  <p>How do you preview your content without invalidating the cache? I want my clients to immediately see the changes they made without waiting for 30 minutes (cdn cache expiration).</p>
  
  <p>Any ideas?</p>
  
  <p>edit #1: </p>
  
  <p>I am wondering if relative urls for linking between pages has any pit falls. </p>
  
Tags: <routing><aws>
Title: CraftCMS with Cloudfront Full Page Delivery
ThreadText: # CraftCMS with Cloudfront Full Page Delivery
  
  (Asked by: username_0 on 2017-02-02)
  
  I have a fully static website. All images and videos are currently delivered via aws cloudfront.
  
  Now I am thinking of delivering the HTML via cloudfront as well. My concern is that craftCMS routing will always point to the CDN domain.
  
  How do you preview your content without invalidating the cache? I want my clients to immediately see the changes they made without waiting for 30 minutes (cdn cache expiration).
  
  Any ideas?
  
  edit #1:
  
  I am wondering if relative urls for linking between pages has any pit falls.
  
  **Tags:** routing, aws
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2017-02-02. Score: 3
  
  That's the dream, isn't it? CDN everywhere, no database hits, etc. How "static" is your site? Unlike other CMS, the great thing about Craft is that you can store information everywhere and pull it out anywhere. That gets to be dynamic content problem nightmare unless you're very diligent about knowing what will happen, for example: "updating this page will also update content on the home page, the blog index, related white papers section, author archives, etc".
  
  Let' say you update the title of one of your main areas that's also part of your navigation: `Services` becomes `Products` for example. Now you have to invalidate every single page.
  
  So it can get complex quickly but if you have a very simple site, obviously, the above doesn't apply.
  
  One way to pull this off would be to create a subdomain, like `admin.whatever.com`. Your admins would login to this URL. As far as Craft is concerned, it'll serve up on whatever domain you need, you just need multiple environment [`config.php`](https://craftcms.com/docs/multi-environment-configs) and template trickery.
  
  In your template files, check for the server name.
  
  ```
  {% if craft.request.serverName is not "domain.com" %} {% reqireLogin %} {% endif %}
  
  ```
  
  This will prevent non-logged in users from trying to accesses the admin pages, otherwise Craft will serve up your non-CDN on that domain to anyone who hits it (which is not something you want to have happen generally).
  
  Unlike something like WordPress where it actually stores URLs in the database, Craft uses reference tags and builds up the URL on the fly so you generally don't have to worry about relative vs absolute URLs.
  
  The hardest part of this is going to be the cache invalidation. Unlike static files, where you can just upload a new file with a different filename on the CDN to invalidate them, pages are much different. To make matters worse, it can [take up to 10-15 minutes](http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html#InvalidationLimits) for that invalidation to happen on Cloudfront.
  
  I use nginx here for static/microcaching and it works pretty well but the idea is the same. I can share some code I use to invalidate its cache but basically you want to create a plugin that listens on `entries.SaveEntry` and then tell CloudFront to invalidate the cache after it's saved. Something like:
  
  ```
  public function init()
  {
  
      parent::init();
      craft()->on('entries.saveEntry', function (Event $event) {
  
          $entry = $event->params['entry'];
  
          if ($entry->url && $entry->enabled) {            
  
          $url = $entry->url;
  
              try {
  
                   // do CloudFront stuff here
                  if (!$response->isSuccessful()) {
                      return;
                  }               
  
              } catch (Exception $e) {
                  // something happened.                  
              }
  
          }
      });
  }
  
  ```
  
  > **Comments:**
  > **username_0**: Thanks for the comprehensive answer. I am wondering how the 'multiple environment config.php and template trickery' might look like  
  
  ---
  
  