自定义 head

这是默认的 head

这样的 head 并不能满足我们的需求.next 公开了一个内置组件,用于将元素追加到<head>标签的.我们可以通过这个自定义 head

新建 components/Head.js

  1. import { Fragment } from "react";
  2. import Head from "next/head";
  3. function MyHead() {
  4. return (
  5. <Fragment>
  6. <Head>
  7. <meta charset="utf-8"></meta>
  8. <meta name="referrer" content="origin"></meta>
  9. <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1"></meta>
  10. <meta name="keywords" content="next.js,react.js"></meta>
  11. <meta content="next 简介 next.js作为一款轻量级的应用框架,主要用于构建静态网站和后端渲染网站。 next 特点 默认情况下由服务器呈现 自动代码拆分可加快页面加载速度 简单的客户端路由(基于页面) 基于"></meta>
  12. <title>蓝猫</title>
  13. </Head>
  14. </Fragment>
  15. );
  16. }
  17. export default MyHead;

为了避免重复的标签,您<head>可以使用 key 属性,以确保标签仅呈现一次

在 MyLayout.js 引入

  1. import Head from "./Head";
  2. ......
  3. <Fragment>
  4. <Head />
  5. <Header />
  6. <div className={"content"}>{children}</div>
  7. <Footer />
  8. </Fragment>
  9. ......

添加完之后的 head 标签,但是在使用中<meta charset="utf-8"></meta>如果再添加的话就会出现两个,去掉 Head 组件中的 charset.

自定义 app

上面是 next 的渲染流程,next 使用 app 组件来进行初始化页面. 可以覆盖 next 自带的 app 来进行初始化

  • 在页面更改是保持持久布局
  • 当页面切换时保持状态
  • 使用自定义错误处理 componentDidCatch
  • 页面的数据注入

新建 pages/_app.js

  1. import React from "react";
  2. import App from "next/app";
  3. class MyApp extends App {
  4. render() {
  5. const { Component, pageProps } = this.props;
  6. return (
  7. <div className="my-app">
  8. <Component {...pageProps} />
  9. </div>
  10. );
  11. }
  12. }
  13. export default MyApp;

getInitialProps 在 App 中添加自定义设置会影响自动静态优化

自定义 document

  • 自定义<Document>通常用于扩充<html><body>标签
  • 在服务端呈现
  • 初始化服务端时添加文档标记元素
  • 通常实现服务端渲染会使用一些 css-in-js 库,如 styled-components, glamorous 或 emotion。styled-jsx 是 Next.js 自带默认使用的 css-in-js 库

新建 pages/_document.js

  1. import Document, { Html, Head, Main, NextScript } from "next/document";
  2. class MyDocument extends Document {
  3. static async getInitialProps(ctx) {
  4. const initialProps = await Document.getInitialProps(ctx);
  5. return { ...initialProps };
  6. }
  7. render() {
  8. return (
  9. <Html>
  10. <Head />
  11. <body>
  12. <div className="document">
  13. <Main />
  14. <div className="inner-document"></div>
  15. <NextScript />
  16. </div>
  17. </body>
  18. </Html>
  19. );
  20. }
  21. }
  22. export default MyDocument;

钩子 getInitialProps 接收到的参数 ctx 对象都是一样的

  • 回调函数 renderPage 是会执行 React 渲染逻辑的函数(同步),这种做法有助于此函数支持一些类似于 Aphrodite 的 renderStatic 等一些服务器端渲染容器。

注意:<Main />外的 React 组件将不会渲染到浏览器中,所以那添加应用逻辑代码。如果你页面需要公共组件(菜单或工具栏),可以参照上面说的 App 组件代替。

自定义 renderPage

使用 renderPage 的唯一原因是 css-in-js 库需要包裹当前应用并且在服务端渲染下也能正常工作

  1. static async getInitialProps(ctx) {
  2. const originalRenderPage = ctx.renderPage
  3. ctx.renderPage = () =>
  4. originalRenderPage({
  5. // useful for wrapping the whole react tree
  6. enhanceApp: App => App,
  7. // useful for wrapping in a per-page basis
  8. enhanceComponent: Component => Component,
  9. })
  10. // Run the parent `getInitialProps` using `ctx` that now includes our custom `renderPage`
  11. const initialProps = await Document.getInitialProps(ctx)
  12. return initialProps
  13. }

自定义错误页面

客户端和服务器端的 404 或 500 错误默认由 error.js 组件处理。

新建 pages/_error.js 覆盖

  1. import React from 'react'
  2. function Error({ statusCode }) {
  3. return (
  4. <p>
  5. {statusCode
  6. ? `An error ${statusCode} occurred on server`
  7. : 'An error occurred on client'}
  8. </p>
  9. )
  10. }
  11. Error.getInitialProps = ({ res, err }) => {
  12. const statusCode = res ? res.statusCode : err ? err.statusCode : 404
  13. return { statusCode }
  14. }

自定义配置 / 自定义 Webpack 配置 / 自定义 babel 配置

当前的配置./next.config.js

  1. const fetch = require("isomorphic-unfetch");
  2. const withBundleAnalyzer = require("@zeit/next-bundle-analyzer");
  3. const withLess = require("@zeit/next-less");
  4. const FilterWarningsPlugin = require("webpack-filter-warnings-plugin");
  5. if (typeof require !== "undefined") {
  6. require.extensions[".less"] = file => {};
  7. }
  8. function HACK_removeMinimizeOptionFromCssLoaders(config) {
  9. config.module.rules.forEach(rule => {
  10. if (Array.isArray(rule.use)) {
  11. rule.use.forEach(u => {
  12. if (u.loader === "css-loader" && u.options) {
  13. delete u.options.minimize;
  14. }
  15. });
  16. }
  17. });
  18. }
  19. module.exports = withBundleAnalyzer(
  20. withLess({
  21. poweredByHeader: false,
  22. analyzeServer: ["server", "both"].includes(process.env.BUNDLE_ANALYZE),
  23. analyzeBrowser: ["browser", "both"].includes(process.env.BUNDLE_ANALYZE),
  24. bundleAnalyzerConfig: {
  25. server: {
  26. analyzerMode: "static",
  27. reportFilename: "../bundles/server.html"
  28. },
  29. browser: {
  30. analyzerMode: "static",
  31. reportFilename: "../bundles/client.html"
  32. }
  33. },
  34. exportPathMap: async function() {
  35. const paths = {
  36. "/": { page: "/" },
  37. "/books": { page: "/books" },
  38. "/article": { page: "/article" },
  39. "/write": { page: "/write" }
  40. };
  41. const res = await fetch("https://api.tvmaze.com/search/shows?q=batman");
  42. const data = await res.json();
  43. const shows = data.map(entry => entry.show);
  44. shows.forEach(show => {
  45. paths[`/book/${show.id}`] = {
  46. page: "/book/[id]",
  47. query: { id: show.id }
  48. };
  49. });
  50. return paths;
  51. },
  52. lessLoaderOptions: {
  53. javascriptEnabled: true
  54. },
  55. webpack(config) {
  56. config.plugins.push(
  57. new FilterWarningsPlugin({
  58. exclude: /mini-css-extract-plugin[^]*Conflicting order between:/
  59. })
  60. );
  61. HACK_removeMinimizeOptionFromCssLoaders(config);
  62. return config;
  63. }
  64. })
  65. );

当前的.babelrc

  1. {
  2. "presets": ["next/babel"],
  3. "plugins": [
  4. [
  5. "import",
  6. {
  7. "libraryName": "antd",
  8. "style": "less"
  9. }
  10. ]
  11. ]
  12. }

Doc

[Next] 五.next自定义内容的更多相关文章

  1. 使用WebBrowser控件时在网页元素上绘制文本或其他自定义内容

    原文:使用WebBrowser控件时在网页元素上绘制文本或其他自定义内容 第一次在CNBlogs上发Post是提出一个有关使用WebBrowser控件时对SELECT网页元素操作的疑惑,这个问题至今也 ...

  2. 微信分享config:ok 但自定义内容无效

    一.问题 使用微信 JSSDK 分享,出现自定义内容无效 ,也就是分享出去的内容不是你配置的内容. 但在调试过程中发现 congfig 都是 ok 的 二.解决 检查config 配置是否正确 js ...

  3. finecms如何调用自定义内容

    我们建站的时间经常会有一些固定的元素,比如电话.地址等,这种相对比较简单的东西可以让编辑人员直接在后台就可以定义,那么finecms有没有这个功能呢?怎么定义?如何调用? finecms后台有一个自定 ...

  4. ueditor插入自定义内容和样式

    UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点   通过UEditor提供的API接口可以很方便的读写操作内容并设置编辑器里的样式   页 ...

  5. SpringBoot入门(五)——自定义配置

    本文来自网易云社区 大部分比萨店也提供某种形式的自动配置.你可以点荤比萨.素比萨.香辣意大利比萨,或者是自动配置比萨中的极品--至尊比萨.在下单时,你并没有指定具体的辅料,你所点的比萨种类决定了所用的 ...

  6. vue-基于elementui自定义主题更换皮肤及自定义内容的皮肤跟换

    参考这篇博客https://blog.csdn.net/young_Emily/article/details/78591261做一遍,加上自己的一些理解 思路:通过自己上一篇博客https://ww ...

  7. dede自定义内容模型下,列表只显示10条的问题及解决方法

    <div class="zjtd-content-ld s-content"> {dede:arclist tagid='ld' row='100' pagesize= ...

  8. C#微信公众号开发 -- (五)自定义菜单创建

    公众号中,底部都是有自己定义的功能按钮,通过点击某个按钮来实现指定的业务逻辑操作. 下面就来说说这些按钮是怎样放到微信公众平台的,还是先来看看微信的官方解释: 请注意: 1.自定义菜单最多包括3个一级 ...

  9. Android UI 绘制过程浅析(五)自定义View

    前言 这已经是Android UI 绘制过程浅析系列文章的第五篇了,不出意外的话也是最后一篇.再次声明一下,这一系列文章,是我在拜读了csdn大牛郭霖的博客文章<带你一步步深入了解View> ...

随机推荐

  1. Hadoop-2.7.5完全分布式搭建

    1.在虚拟机上安装Hadoop完全分布式准备工作 1)这里使用的是VMWare软件,在VMWare上安装一个CentOS6.5,并再克隆两个机器配置相关MAC地址,以及配置机器名 2)三台虚拟机配置好 ...

  2. Riot.js——一个小而美的JS框架

    Riot.js是什么? Riot 拥有创建现代客户端应用的所有必需的成分: "响应式" 视图层用来创建用户界面 用来在各独立模块之间进行通信的事件库 用来管理URL和浏览器回退按钮 ...

  3. Joda-DateTime Date 与 String 相互转换

    [参考文章]:Joda-Time 的 DateTimeFormat 问题 public class DateFormatUtils { /** HH 必须大写 */ public static fin ...

  4. python3笔记目录大纲汇总

    篇一.python3基础知识和语句 python3笔记一:python基础知识 python3笔记二:进制转换与原码反码补码 python3笔记三:运算符与表达式 python3笔记四:if语句 py ...

  5. DL反向传播理解

    作者:寒小阳 时间:2015年12月. 出处:http://blog.csdn.net/han_xiaoyang/article/details/50321873 声明:版权所有,转载请联系作者并注明 ...

  6. String,int,Integer之间的转换

    public class Test{ public static void main(String[] args) { //int转换成Integer Integer in = new Integer ...

  7. leetcode-hard-array-41. First Missing Positive-NO

    mycode class Solution(object): def firstMissingPositive(self, nums): """ :type nums: ...

  8. 使用data_flow_ops构造batch数据集

    1. tf.unstack(number, axis=0)  表示对数据进行拆分 import tensorflow as tf import numpy as np data = np.array( ...

  9. [go]new和make开辟内存

    var申明取址和new效果一样 值类型 引用类型 make和new的区别 内置函数new按指定类型长度分配零值内存,返回指针,并不关心类型内部构造和初始化方式. 而引用类型则必须使用make函数创建, ...

  10. ListView中用鼠标拖动各项上下移动的问题。(100分)

    在OnDragDrop事件中處理:以下是delphi的例子 procedure TForm1.ListBox1DragOver(Sender, Source: TObject; X, Y: Integ ...