My organization is using Ember addons to develop a set of shared components between our applications. Let's call this repository app-components. Currently the components application's primary responsibility is to distribute CSS, fonts and images.
We are also building a living styleguide that will ingest our shared components and present them in a neutral way for developers to reference. Let's call this repository app-styleguide. Our goal is to deploy app-styleguide using ember-deploy to deploy this solution to Github Pages. The url follows this pattern:
https://organization.github.io/app-styleguide/
When the app-styleguide application makes it to the gh-pages branch and is served as a webpage, all of the fonts and images being delivered by app-components are giving us a 404. I have referenced a handful of different solutions to this problem, but I keep coming across the same solutions that we have tried.
I have tried using the following two ember addons that automate the deploy to github pages:
https://github.com/poetic/ember-cli-github-pages
https://www.npmjs.com/package/ember-cli-deploy-gh-pages
In the end we went with a vanilla ember-cli-deploy solution, as those two addons are quite old...
I have followed the instructions here to add rootUrl andlocationTypeproperties to ourenvironment.js` file, which has not worked:
https://github.com/ember-cli/ember-cli/issues/398
Our environment.js file looks like this:
if (environment === 'production') {
ENV.rootURL = '/app-styleguide';
ENV.locationType = 'hash';
}
And our requests continue to not add app-styleguide to the request URL's for assets coming from the Addon. Here is an example of a failed request from the Chrome DevTools Network tab:
Request URL:https://organization.github.io/assets/images/thumbnail-icons/person.svg
Request Method:GET
Status Code:404 Not Found
As you can see, app-styleguide is not added to the request.
Any help is greatly appreciated!
I was able to receive some help over on the Ember Slack Community
(special thanks to #alexspeller). It turns out I needed to update a couple of settings in the fingerprinting of assets.
Using the included broccoli-asset-rev library I had to modify my ember-cli-build.js to include the following:
var app = new EmberApp(defaults, {
fingerprint: {
extensions: ['js', 'css', 'png', 'jpg', 'gif', 'map', 'svg', 'ttf', 'woff'],
prepend: '/app-styleguide/'
}
});
I needed to update the options to account for SVG, TTF, & WOFF, as well as the proper prepended url segment.
You can read about the functionality here:
https://ember-cli.com/asset-compilation#fingerprinting-and-cdn-urls
Available options:
https://github.com/cibernox/broccoli-asset-rev?files=1#options
Related
Setup
I'm using GitHub Pages to host my website statically. To generate SEO data I'm using the native head() method supported by the Nuxt framework. Here is a sample of my setup.
export default {
head() {
return meta({
title: 'Page title here',
description: "Page description here",
image: this.image, // programmatic image
})
}
}
Issue
As expected with a single page application, the metadata is being rendered into the DOM as the page is loaded. The initial data in the HTML comes from the nuxt.config.js, information designated for my homepage. This is causing an issue that when any page gets scraped they all have the same metadata.
Goal
Is it possible to render each page's metadata in their respective HTML files when running nuxt generate? This way the appropriate metadata is available when Google, Facebook, Instagram, and other platforms scrape metadata.
With some help from #kissu, the issue was caused by the fact that in my nuxt.config.js I had the Server Side Rendering turned off with the following property being st ssr: false when it should have been ssr: true. There were subsequent issues with Node JS that needed to be resolved along the way.
You need to use ssr: true if you need some SEO, otherwise it will only stay as an SPA.
target can be either server (default) or static.
I am using the ember quick-start tutorial app. Everything works great locally, but when deployed to a test environment the app is 404ing on loading all resources.
I am deployed to a subfolder out somewhere and apparently ember is trying to find it against the root domain, instead of subfolder
Example:
http://example.com/embertest/index.html
The assets folder is obviously under http://example.com/embertest/assets/, but on load it's trying to grab it from http://example.com/assets/ which doesn't exist
How can I have ember use relative paths in this case?
Update 1
After some googling I tried editing the environment.js ENV.baseURL attribute
In the if(environment === 'production') block I added ENV.baseURL = '/website/dist/';, obviously I am building with ember build --env production
I am getting same 404s when going directly to a route but now also getting an error on index.html, Uncaught UnrecognizedURLError: /index.html
I tried every combination of '/website/dist/', 'website/dist/', '/website/dist' as well
Update 2
I have now also tried manually editing the <base href="/website/dist/"> in my index.html after a prod build. Same errors as from update 1
You need to understand that you can't just put an ember application to a normal webserver folder. Ember uses the history API to change the URL when you do a route change but it can't control what your web server deploys when its directly fetched.
So you have your ember index.html on http://example.com/app/index.html your web server usually will only deploy this file when you open http://example.com/app/ or http://example.com/app/index.html. But for a route foo your url is http://example.com/app/foo and your web server is looking for a directly foo that does not exist. So you have to configure your web server so its always responding with your index.html if your not requesting another existing resource (like an image, js or css file)!
How to do this depends completely on your webserver.
You must also notice that you should enter your assets in a full root relative path and specify rootURL so your router knows which part of the URL is your path and where your routing begins.
You should not use baseURL because its an upcoming deprecation!
You really should read this really new blog post!
Use ENV.locationType = 'hash' to prevent the usage of the history API is still always an option, but definitly an ugly one.
Okay so I solved this by changing ENV.locationType = 'hash' in environment.js
Would still love an explanation of what's going on as this feels a little bit hacky...
I have built an ember application which has two routes say route1 and route2.
I got the compiled files from dist folder. I put those files in a tomcat server.
When i try to access that file through index.html, it works fine. But how can i navigate to a route in that compiled application?
Normally in ember-cli development environment, we navigation to a route using server:port/route_name
How can i perform the same operation in index.html without using any hyperlinks for routes?
Edit:
Got the answer. Setting ENV.locationType = 'hash' solved the navigation problem. I was able to access the route using index.html#/route_name
But I am still stuck with how to integrate ember app into a non-ember app.
Got the answer.
Setting ENV.locationType = 'hash' solved the navigation problem. I was able to access the route using index.html#/route_name
Setting ENV.APP.rootElement = '#ember-testing' solved inserting ember app into non-ember app. Create a div with the rootElement ID and then ember will automatically place the app inside the div.
Loading my ember CLI app currently involved downloading a 3Mb file, most of which consists of common libraries such as jquery, ember, bootstrap, etc. 3Mb is not huge, but it becomes noticable over a slow connection so I want to strip out all the common libraries and get them from a CDN instead. The idea is that they would be cached by the browser to that they don't need to be re-downloaded every time I update my app (which is very often at the moment). I have read this question, which points out that it is easy to simply add a <script...> to index.html, but I can't figure out how to them tell ember not to package those libraries into vendor.js.
In brocfile.js (ember-cli-build.js in newer versions) change the constructor to
var app = new EmberApp({
vendorFiles: {
'jquery.js': false,
'handlebars.js': false,
'ember.js': false
}
});
Now include those in your index.html the old fashion way and enjoy the fact that pretty much every users browser already has jquery cached even if they haven't visited your site before.
This is something you get by default with ember-cli. From the manual:
When the environment is production (e.g. ember build --environment=production), the addon will automatically fingerprint your js, css, png, jpg, and gif assets by appending an md5 checksum to the end of their filename (e.g. assets/yourapp-9c2cbd818d09a4a742406c6cb8219b3b.js). In addition, your html, js, and css files will be re-written to include the new name.
You can then modify your Brocfile.js to tell it what the base url for your cdn is:
prepend - Default: '' - A string to prepend to all of the assets. Useful for CDN urls like https://subdomain.cloudfront.net/
What is the best approach to use EAK and ember-data-tastypie-adapter?
I am currently trying the following:
Django running on localhost:7000
EAK running on localhost:8000
Added ember-data-tastypie-adapter to bower.json
Added both JS files to index.html
<script src="/vendor/ember-data-tastypie-adapter/packages/ember-data-tastypie-adapter/lib/tastypie_adapter.js"></script>
<script src="/vendor/ember-data-tastypie-adapter/packages/ember-data-tastypie-adapter/lib/tastypie_serializer.js"></script>
Created everything needed on Django side
I figured that I had to create serializers/application.js and put in it:
export default DS.DjangoTastypieSerializer.extend();
Also adapters/application.js needed adjustments:
export default DS.DjangoTastypieAdapter.extend({
serverDomain: 'http://localhost:7000',
});
Requests go to Django and responses are sent.
However in EAK this gives "Sorry, something went wrong" message without any further information (empty error message box). No errors in console either.
If I remove serializers/application.js I get similar message, in this case with information about the error:
Assertion Failed: Nested controllers need be referenced as [/django/tastypie],
instead of [_djangoTastypie].
Refer documentation: http://iamstef.net/ember-app-kit/guides/naming-conventions.html
Do I have to define defaultSerializer in adapters/application.js? If so, what is it, /django/tastypie or something else?
What am I missing to integrate ember-data-tastypie-adapter in EAK? Trouble is, I have not seen any example where EAK and tastypie would be working together.
Of course this two local server system is development environment. Production is planned like here, both API and JS is served by one Django instance.
UPDATE:
Creating deployment code by grunt dist and serving it using Django works.
I suspect that problem lies with different JSON origin.
Turns out, that EAK has API proxy option.
Updated package.json to my API settings:
"proxyURL": "http://localhost:7000",
"proxyPath": "/api/v1",
Removed custom settings from adapters/application.js.
Now running grunt server:proxy gets data from Django. And ember.js app works without errors, not being same origin was most likely the problem.